示例#1
0
 public Artifact()
 {
     for (int i = 0; i < Misc.MAX_PVAL; i++)
     {
         pval_flags[i] = new Bitflag(Object_Flag.SIZE);
     }
 }
示例#2
0
        /**
         * Notice any slays on a particular object which are in mask.
         *
         * \param o_ptr is the object on which we are noticing slays
         * \param mask is the flagset within which we are noticing them
         */
        //mask was size: Object_Flag.SIZE. It might not even be an array, but just a bitflag with that size...
        //It might end up being an out parameter...
        public static void object_notice_slays(Object o_ptr, Bitflag mask)
        {
            throw new NotImplementedException();
            //bool learned;
            //bitflag f[Object_Flag.SIZE];
            //char o_name[40];
            //int i;

            ///* We are only interested in the flags specified in mask */
            //object_flags(o_ptr, f);
            //Object_Flag.inter(f, mask);

            ///* if you learn a slay, learn the ego and print a message */
            //for (i = 0; i < SL_MAX; i++) {
            //    const struct slay *s_ptr = &slay_table[i];
            //    if (Object_Flag.has(f, s_ptr.object_flag)) {
            //        learned = object_notice_flag(o_ptr, s_ptr.object_flag);
            //        if (EASY_LEARN && learned) {
            //            object_notice_ego(o_ptr);
            //            object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
            //            msg("Your %s %s!", o_name, s_ptr.active_verb);
            //        }
            //    }
            //}

            //object_check_for_ident(o_ptr);
        }
示例#3
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);
        }
示例#4
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;
                    }
                }
            }
        }
示例#5
0
        /**
         * Determine whether a flagset includes any curse flags.
         */
        public static bool cursed_p(Bitflag f)
        {
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            f2.wipe();
            create_mask(f2, false, object_flag_type.CURSE);

            return(f.is_inter(f2));
        }
示例#6
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();
            }
        }
示例#7
0
        /*
         * Checks for additional knowledge implied by what the player already knows.
         *
         * \param o_ptr is the object to check
         *
         * returns whether it calls object_notice_everyting
         */
        bool check_for_ident()
        {
            Bitflag flags       = new Bitflag(Object_Flag.SIZE);
            Bitflag known_flags = new Bitflag(Object_Flag.SIZE);
            Bitflag f2          = new Bitflag(Object_Flag.SIZE);

            object_flags(ref flags);
            object_flags_known(ref known_flags);

            /* Some flags are irrelevant or never learned or too hard to learn */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.INT,
                                    Object_Flag.object_flag_type.IGNORE,
                                    Object_Flag.object_flag_type.HATES);

            flags.diff(f2);
            known_flags.diff(f2);

            if (!flags.is_equal(known_flags))
            {
                return(false);
            }

            /* If we know attack bonuses, and defence bonuses, and effect, then
             * we effectively know everything, so mark as such */
            if ((attack_plusses_are_visible() || (was_sensed() && to_h == 0 && to_d == 0)) &&
                (defence_plusses_are_visible() || (was_sensed() && to_a == 0)) &&
                (effect_is_known() || effect() == null))
            {
                /* In addition to knowing the pval flags, it is necessary to know the pvals to know everything */
                int i;
                for (i = 0; i < num_pvals; i++)
                {
                    if (!this_pval_is_visible(i))
                    {
                        break;
                    }
                }
                if (i == num_pvals)
                {
                    notice_everything();
                    return(true);
                }
            }

            /* We still know all the flags, so we still know if it's an ego */
            if (ego != null)
            {
                /* require worn status so you don't learn launcher of accuracy or gloves of slaying before wield */
                if (was_worn())
                {
                    notice_ego();
                }
            }

            return(false);
        }
示例#8
0
        /**
         * Get a random slay (or brand).
         * We use randint1 because the first entry in slay_table is null.
         *
         * \param mask is the set of slays from which we are choosing.
         */
        //mask.size = Object_Flag.SIZE
        public static Slay random_slay(Bitflag mask)
        {
            throw new NotImplementedException();
            //const struct slay *s_ptr;
            //do {
            //    s_ptr = &slay_table[randint1(SL_MAX - 1)];
            //} while (!Object_Flag.has(mask, s_ptr.object_flag));

            //return s_ptr;
        }
示例#9
0
        public byte xtra; /* Extra sustain/resist/power */

        #endregion Fields

        #region Constructors

        public Ego_Item()
        {
            for(int i = 0; i < Misc.MAX_PVALS; i++) {
                pval_flags[i] = new Bitflag(Object_Flag.SIZE);
            }

            to_h = new random_value();
            to_d = new random_value();
            to_a = new random_value();
        }
示例#10
0
        /**
         * Log the names of a flagset to a file.
         *
         * \param f is the set of flags we are logging.
         * \param log_file is the file to which we are logging the names.
         */
        //log_file was type ang_file... I don't think we need that anymore...
        public static void log_flags(Bitflag f, FileStream log_file)
        {
            throw new NotImplementedException();
            //int i;

            //file_putf(log_file, "Object flags are:\n");
            //for (i = 0; i < OF_MAX; i++)
            //    if (of_has(f, i))
            //        file_putf(log_file, "%s\n", flag_names[i]);
        }
示例#11
0
 /**
  * React to slays which hurt a monster
  *
  * \param obj_flags is the set of flags we're testing for slays
  * \param mon_flags is the set of flags we're adjusting as a result
  */
 //both are probably arrays
 public static void react_to_slay(Bitflag obj_flags, Bitflag mon_flags)
 {
     throw new NotImplementedException();
     //int i;
     //for (i = 0; i < SL_MAX; i++) {
     //    const struct slay *s_ptr = &slay_table[i];
     //    if (Object_Flag.has(obj_flags, s_ptr.object_flag) && s_ptr.monster_flag)
     //        Monster_Flag.on(mon_flags, s_ptr.monster_flag);
     //}
 }
示例#12
0
        public Ego_Item()
        {
            for (int i = 0; i < Misc.MAX_PVALS; i++)
            {
                pval_flags[i] = new Bitflag(Object_Flag.SIZE);
            }

            to_h = new random_value();
            to_d = new random_value();
            to_a = new random_value();
        }
示例#13
0
        /**
         * Notice a given special flag on wielded items.
         *
         * \param flag is the flag to notice
         */
        public static void wieldeds_notice_flag(Player.Player p, int flag)
        {
            int i;

            /* Sanity check */
            if (flag == 0)
            {
                return;
            }

            /* XXX Eddie need different naming conventions for starting wieldeds at INVEN_WIELD vs INVEN_WIELD+2 */
            for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++)
            {
                Object  o_ptr = p.inventory[i];
                Bitflag f     = new Bitflag(Object_Flag.SIZE);

                if (o_ptr.kind == null)
                {
                    continue;
                }

                o_ptr.object_flags(ref f);

                if (f.has(flag) && !o_ptr.known_flags.has(flag))
                {
                    //char o_name[80];
                    string o_name = o_ptr.object_desc(Detail.BASE);

                    /* Notice the flag */
                    o_ptr.notice_flag(flag);

                    /* XXX Eddie should this go before noticing the flag to avoid learning twice? */
                    if (EASY_LEARN && o_ptr.is_jewelry())
                    {
                        /* XXX Eddie EASY_LEARN Possible concern: gets =teleportation just from +2 speed */
                        o_ptr.flavor_aware();
                        o_ptr.check_for_ident();
                    }

                    /* Message */
                    Object_Flag.flag_message(flag, o_name);
                }
                else
                {
                    /* Notice that flag is absent */
                    o_ptr.notice_flag(flag);
                }

                /* XXX Eddie should not need this, should be done in noticing, but will remove later */
                o_ptr.check_for_ident();
            }

            return;
        }
示例#14
0
        /**
         * Fill in a value in the slay cache. Return true if a change is made.
         *
         * \param index is the set of slay flags whose value we are adding
         * \param value is the value of the slay flags in index
         */
        public static bool fill_slay_cache(Bitflag index, int value)
        {
            for (int i = 0; !slay_cache[i].flags.is_empty(); i++)
            {
                if (index.is_equal(slay_cache[i].flags))
                {
                    slay_cache[i].value = value;
                    return(true);
                }
            }

            return(false);
        }
示例#15
0
        static int obj_desc_light(Object o_ptr, ref string buf, int max, int end)
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);

            o_ptr.object_flags(ref f);

            /* Fuelled light sources get number of remaining turns appended */
            if ((o_ptr.tval == TVal.TV_LIGHT) && !f.has(Object_Flag.NO_FUEL.value))
            {
                buf += String.Format(" ({0} turns)", o_ptr.timeout);
            }

            return(buf.Length);
        }
示例#16
0
        /**
         * Check the slay cache for a combination of slays and return a slay value
         *
         * \param index is the set of slay flags to look for
         */
        //index might be an array
        public static int check_slay_cache(Bitflag index)
        {
            int i;

            for (i = 0; !slay_cache[i].flags.is_empty(); i++)
            {
                if (index.is_equal(slay_cache[i].flags))
                {
                    break;
                }
            }

            return(slay_cache[i].value);
        }
示例#17
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;
        }
示例#18
0
        /*
         * Obtain the "flags" for the player as if he was an item
         */
        public static void player_flags(ref Bitflag f)
        {
            if (f == null)
            {
                f = new Bitflag(Object.Object_Flag.SIZE);
            }
            /* Add racial flags */
            f.copy(instance.Race.flags);

            /* Some classes become immune to fear at a certain plevel */
            if (instance.player_has(Misc.PF.BRAVERY_30.value) && instance.lev >= 30)
            {
                f.on(Object.Object_Flag.RES_FEAR.value);
            }
        }
示例#19
0
        public char x_char; /**< Desired object character (set by user/pref file) */

        #endregion Fields

        #region Constructors

        public Object_Kind()
        {
            for(int i = 0; i < Misc.MAX_PVALS; i++) {
                pval_flags[i] = new Bitflag(Object_Flag.SIZE);
            }
            to_h = new random_value();
            to_d = new random_value();
            to_a = new random_value();

            for(int i = 0; i < pval.Length; i++) {
                pval[i] = new random_value();
            }

            effect = Effect.XXX;
            time = new random_value();
        }
示例#20
0
        /**
         * Determine whether an object flag or its timed equivalent are set in the
         * passed-in flags (which probably come from a state structure). This assumes
         * that there are no p_ptr.timed effects which can be active yet unknown to
         * the player.
         *
         * \param p player to act upon
         * \param flag is the object flag for which we are checking.
         * \param f is the set of flags we're checking
         */
        public bool check_state(Object.Object_Flag flag, Bitflag f)
        {
            Object_Flag of_ptr = Object_Flag.list[flag.value];

            /* Sanity check */
            if (flag == null)
            {
                return(false);
            }

            if (f.has(flag.value) || (of_ptr.timed != (Timed_Effect)0 && timed[(int)of_ptr.timed] > 0))
            {
                return(true);
            }

            return(false);
        }
示例#21
0
        /*
         * Notice a set of flags - returns true if anything new was learned
         */
        bool notice_flags(Bitflag flags)
        {
            throw new NotImplementedException();
            //if (!of_is_subset(o_ptr.known_flags, flags))
            //{
            //    of_union(o_ptr.known_flags, flags);
            //    /* XXX Eddie don't want infinite recursion if object_check_for_ident sets more flags,
            //     * but maybe this will interfere with savefile repair
            //     */
            //    object_check_for_ident(o_ptr);
            //    event_signal(EVENT_INVENTORY);
            //    event_signal(EVENT_EQUIPMENT);

            //    return true;
            //}

            //return false;
        }
示例#22
0
        public Object_Kind()
        {
            for (int i = 0; i < Misc.MAX_PVALS; i++)
            {
                pval_flags[i] = new Bitflag(Object_Flag.SIZE);
            }
            to_h = new random_value();
            to_d = new random_value();
            to_a = new random_value();

            for (int i = 0; i < pval.Length; i++)
            {
                pval[i] = new random_value();
            }

            effect = Effect.XXX;
            time   = new random_value();
        }
示例#23
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);
        }
示例#24
0
        /**
         * Notice curses on an object.
         *
         * \param o_ptr is the object to notice curses on
         */
        bool notice_curses()
        {
            Bitflag f  = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            object_flags(ref f);

            /* Gather whatever curse flags there are to know */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.CURSE);

            /* Remove everything except the curse flags */
            f.inter(f2);

            /* give knowledge of which curses are present */
            notice_flags(f);

            check_for_ident();

            Misc.p_ptr.notice |= Misc.PN_SQUELCH;

            return(!f.is_empty());
        }
示例#25
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);
        }
示例#26
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;
        }
示例#27
0
        static int obj_desc_pval(Object o_ptr, string buf, int max, int end, bool spoil)
        {
            Bitflag f  = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);
            int     i;

            o_ptr.object_flags(ref f);
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.PVAL, Object_Flag.object_flag_type.STAT);

            if (!f.is_inter(f2))
            {
                return(end);
            }

            buf += " <";
            //strnfcat(buf, max, &end, " <");
            for (i = 0; i < o_ptr.num_pvals; i++)
            {
                if (spoil || o_ptr.this_pval_is_visible(i))
                {
                    if (i > 0)
                    {
                        buf += ", ";
                        //strnfcat(buf, max, &end, ", ");
                    }
                    buf += o_ptr.pval[i] > 0 ? "+" + o_ptr.pval[i] : o_ptr.pval[i].ToString();
                    //strnfcat(buf, max, &end, "%+d", o_ptr.pval[i]);
                }
            }

            buf += ">";
            end  = buf.Length;            //f**k it.
            //strnfcat(buf, max, &end, ">");

            return(end);
        }
示例#28
0
        /*
         * Obtain the "flags" for the player as if he was an item
         */
        public static void player_flags(ref Bitflag f)
        {
            if(f == null) {
                f = new Bitflag(Object.Object_Flag.SIZE);
            }
            /* Add racial flags */
            f.copy(instance.Race.flags);

            /* Some classes become immune to fear at a certain plevel */
            if (instance.player_has(Misc.PF.BRAVERY_30.value) && instance.lev >= 30)
                f.on(Object.Object_Flag.RES_FEAR.value);
        }
示例#29
0
        static int obj_desc_combat(Object o_ptr, ref string buf, int max, int end, bool spoil)
        {
            Bitflag flags       = new Bitflag(Object_Flag.SIZE);
            Bitflag flags_known = new Bitflag(Object_Flag.SIZE);

            o_ptr.object_flags(ref flags);
            o_ptr.object_flags_known(ref flags_known);

            if (flags.has(Object_Flag.SHOW_DICE.value))
            {
                /* Only display the real damage dice if the combat stats are known */
                if (spoil || o_ptr.attack_plusses_are_visible())
                {
                    buf = buf + " (" + o_ptr.dd + "d" + o_ptr.ds + ")";
                }
                else
                {
                    buf = buf + " (" + o_ptr.kind.dd + "d" + o_ptr.kind.ds + ")";
                }
            }

            if (flags.has(Object_Flag.SHOW_MULT.value))
            {
                /* Display shooting power as part of the multiplier */
                if (flags.has(Object_Flag.MIGHT.value) && (spoil || o_ptr.object_flag_is_known(Object_Flag.MIGHT.value)))
                {
                    buf = buf + " (x" + (o_ptr.sval % 10) + o_ptr.pval[o_ptr.which_pval(Object_Flag.MIGHT.value)] + ")";
                }
                else
                {
                    buf = buf + " (x" + o_ptr.sval % 10 + ")";
                }
            }

            /* Show weapon bonuses */
            if (spoil || o_ptr.attack_plusses_are_visible())
            {
                if (flags.has(Object_Flag.SHOW_MODS.value) || o_ptr.to_d != 0 || o_ptr.to_h != 0)
                {
                    /* Make an exception for body armor with only a to-hit penalty */
                    if (o_ptr.to_h < 0 && o_ptr.to_d == 0 &&
                        (o_ptr.tval == TVal.TV_SOFT_ARMOR ||
                         o_ptr.tval == TVal.TV_HARD_ARMOR ||
                         o_ptr.tval == TVal.TV_DRAG_ARMOR))
                    {
                        buf = buf + " (" + (o_ptr.to_h > 0 ? "+" : "-") + o_ptr.to_h + ")";
                    }

                    /* Otherwise, always use the full tuple */
                    else
                    {
                        buf = buf + " (" + (o_ptr.to_h > 0 ? "+" : "-") + o_ptr.to_h + "," +
                              (o_ptr.to_d > 0 ? "+" : "-") + o_ptr.to_d + ")";
                    }
                }
            }


            /* Show armor bonuses */
            if (spoil || o_ptr.defence_plusses_are_visible())
            {
                if (obj_desc_show_armor(o_ptr))
                {
                    buf = buf + " [" + o_ptr.ac + "," + (o_ptr.to_a > 0?"+":"-") + o_ptr.to_a + "]";
                }
                else if (o_ptr.to_a != 0)
                {
                    buf = buf + " [" + (o_ptr.to_a > 0?"+":"-") + o_ptr.to_a + "]";
                }
            }
            else if (obj_desc_show_armor(o_ptr))
            {
                buf = buf + " [" + (o_ptr.was_sensed() ? o_ptr.ac : o_ptr.kind.ac) + "]";
            }

            return(end);
        }
示例#30
0
        /*
         * Process a monster
         *
         * In several cases, we directly update the monster lore
         *
         * Note that a monster is only allowed to "reproduce" if there
         * are a limited number of "reproducing" monsters on the current
         * level.  This should prevent the level from being "swamped" by
         * reproducing monsters.  It also allows a large mass of mice to
         * prevent a louse from multiplying, but this is a small price to
         * pay for a simple multiplication method.
         *
         * XXX Monster fear is slightly odd, in particular, monsters will
         * fixate on opening a door even if they cannot open it.  Actually,
         * the same thing happens to normal monsters when they hit a door
         *
         * In addition, monsters which *cannot* open or bash down a door
         * will still stand there trying to open it...  XXX XXX XXX
         *
         * Technically, need to check for monster in the way combined
         * with that monster being in a wall (or door?) XXX
         */
        public static void process_monster(Cave c, int m_idx)
        {
            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx];

            int i, oy, ox, ny, nx;

            int[] mm = new int[5];

            bool woke_up = false;
            bool stagger;

            bool do_turn;
            bool do_move;
            bool do_view;

            bool did_open_door;
            bool did_bash_door;

            /* Handle "sleep" */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.SLEEP] != 0)
            {
                uint notice;

                /* Aggravation */
                if (Misc.p_ptr.check_state(Object_Flag.AGGRAVATE, Misc.p_ptr.state.flags))
                {
                    /* Wake the monster */
                    mon_clear_timed(m_idx, (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOTIFY, false);

                    /* Notice the "waking up" */
                    if (m_ptr.ml && !m_ptr.unaware)
                    {
                        //char m_name[80];
                        string m_name;

                        /* Get the monster name */
                        m_name = m_ptr.monster_desc(0);
                        //monster_desc(m_name, sizeof(m_name), m_ptr, 0);

                        /* Dump a message */
                        Utilities.msg("%^s wakes up.", m_name);

                        /* Hack -- Update the health bar */
                        if (Misc.p_ptr.health_who == m_idx) Misc.p_ptr.redraw |= (Misc.PR_HEALTH);
                    }

                    /* Efficiency XXX XXX */
                    return;
                }

                /* Anti-stealth */
                notice = (uint)Random.randint0(1024);

                /* Hack -- See if monster "notices" player */
                if ((notice * notice * notice) <= Misc.p_ptr.state.noise)
                {
                    int d = 1;

                    /* Wake up faster near the player */
                    if (m_ptr.cdis < 50) d = (100 / m_ptr.cdis);

                    /* Still asleep */
                    if (m_ptr.m_timed[(int)Misc.MON_TMD.SLEEP] > d)
                    {
                        /* Monster wakes up "a little bit" */
                        mon_dec_timed(m_idx, (int)Misc.MON_TMD.SLEEP, d , (ushort)Misc.MON_TMD_FLG_NOMESSAGE, false);

                        /* Notice the "not waking up" */
                        if (m_ptr.ml && !m_ptr.unaware)
                        {
                            /* Hack -- Count the ignores */
                            if (l_ptr.ignore < Byte.MaxValue)
                            {
                                l_ptr.ignore++;
                            }
                        }
                    }

                    /* Just woke up */
                    else
                    {
                        /* Reset sleep counter */
                        woke_up = mon_clear_timed(m_idx, (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOMESSAGE, false);

                        /* Notice the "waking up" */
                        if (m_ptr.ml && !m_ptr.unaware)
                        {
                            //char m_name[80];
                            string m_name;

                            /* Get the monster name */
                            m_name = m_ptr.monster_desc(0);

                            /* Dump a message */
                            //Utilities.msg("%^s wakes up.", m_name);
                            Utilities.msg(m_name + " wakes up.");

                            /* Hack -- Update the health bar */
                            if (Misc.p_ptr.health_who == m_idx) Misc.p_ptr.redraw |= (Misc.PR_HEALTH);

                            /* Hack -- Count the wakings */
                            if (l_ptr.wake < byte.MaxValue)
                            {
                                l_ptr.wake++;
                            }
                        }
                    }
                }

                /* Still sleeping */
                if (m_ptr.m_timed[(int)Misc.MON_TMD.SLEEP] != 0) return;
            }

            /* If the monster just woke up, then it doesn't act */
            if (woke_up) return;

            if (m_ptr.m_timed[(int)Misc.MON_TMD.FAST] != 0)
                mon_dec_timed(m_idx, Misc.MON_TMD.FAST, 1, 0, false);

            if (m_ptr.m_timed[(int)Misc.MON_TMD.SLOW] != 0)
                mon_dec_timed(m_idx, Misc.MON_TMD.SLOW, 1, 0, false);

            if (m_ptr.m_timed[(int)Misc.MON_TMD.STUN] != 0)
            {
                throw new NotImplementedException();
                //int d = 1;

                ///* Make a "saving throw" against stun */
                //if (randint0(5000) <= r_ptr.level * r_ptr.level)
                //{
                //    /* Recover fully */
                //    d = m_ptr.m_timed[MON_TMD_STUN];
                //}

                ///* Hack -- Recover from stun */
                //if (m_ptr.m_timed[MON_TMD_STUN] > d)
                //    mon_dec_timed(m_idx, MON_TMD_STUN, 1, MON_TMD_FLG_NOMESSAGE, false);
                //else
                //    mon_clear_timed(m_idx, MON_TMD_STUN, MON_TMD_FLG_NOTIFY, false);

                ///* Still stunned */
                //if (m_ptr.m_timed[MON_TMD_STUN]) return;
            }

            if (m_ptr.m_timed[(int)Misc.MON_TMD.CONF] != 0)
            {
                throw new NotImplementedException();
                //int d = randint1(r_ptr.level / 10 + 1);

                ///* Still confused */
                //if (m_ptr.m_timed[MON_TMD_CONF] > d)
                //    mon_dec_timed(m_idx, MON_TMD_CONF, d , MON_TMD_FLG_NOMESSAGE,
                //        false);
                //else
                //    mon_clear_timed(m_idx, MON_TMD_CONF, MON_TMD_FLG_NOTIFY, false);
            }

            if (m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] != 0)
            {
                /* Amount of "boldness" */
                int d = Random.randint1(r_ptr.level / 10 + 1);

                if (m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] > d)
                    mon_dec_timed(m_idx, Misc.MON_TMD.FEAR, d, Misc.MON_TMD_FLG_NOMESSAGE, false);
                else
                    mon_clear_timed(m_idx, Misc.MON_TMD.FEAR, Misc.MON_TMD_FLG_NOTIFY, false);
            }

            /* Get the origin */
            oy = m_ptr.fy;
            ox = m_ptr.fx;

            /* Attempt to "mutiply" (all monsters are allowed an attempt for lore
             * purposes, even non-breeders)
             */
            if (Misc.num_repro < Misc.MAX_REPRO)
            {
                int k, y, x;

                /* Count the adjacent monsters */
                for (k = 0, y = oy - 1; y <= oy + 1; y++)
                {
                    for (x = ox - 1; x <= ox + 1; x++)
                    {
                        /* Count monsters */
                        if (Cave.cave.m_idx[y][x] > 0) k++;
                    }
                }

                /* Multiply slower in crowded areas */
                if ((k < 4) && (k == 0 || Random.one_in_(k * Misc.MON_MULT_ADJ)))
                {
                    /* Successful breeding attempt, learn about that now */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.MULTIPLY.value);

                    /* Try to multiply (only breeders allowed) */
                    if (r_ptr.flags.has(Monster_Flag.MULTIPLY.value) && multiply_monster(m_idx))
                    {
                        /* Make a sound */
                        if (m_ptr.ml)
                        {
                            //sound(MSG_MULTIPLY); //TODO: enable sound
                        }

                        /* Multiplying takes energy */
                        return;
                    }
                }
            }

            /* Mimics lie in wait */
            if (is_mimicking(m_idx)) return;

            /* Attempt to cast a spell */
            if (make_attack_spell(m_idx)) return;

            /* Reset */
            stagger = false;

            /* Confused */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.CONF] != 0)
            {
                /* Stagger */
                stagger = true;
            }

            /* Random movement - always attempt for lore purposes */
            else
            {
                int roll = Random.randint0(100);

                /* Random movement (25%) */
                if (roll < 25)
                {
                    /* Learn about small random movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.RAND_25.value);

                    /* Stagger */
                    if (r_ptr.flags.test(Monster_Flag.RAND_25.value, Monster_Flag.RAND_50.value)) stagger = true;
                }

                /* Random movement (50%) */
                else if (roll < 50)
                {
                    /* Learn about medium random movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.RAND_50.value);

                    /* Stagger */
                    if (r_ptr.flags.has(Monster_Flag.RAND_50.value)) stagger = true;
                }

                /* Random movement (75%) */
                else if (roll < 75)
                {
                    /* Stagger */
                    if (r_ptr.flags.test_all(Monster_Flag.RAND_25.value, Monster_Flag.RAND_50.value))
                    {
                        stagger = true;
                    }
                }
            }

            /* Normal movement */
            if (!stagger)
            {
                /* Logical moves, may do nothing */
                if (!get_moves(Cave.cave, m_idx, mm)) return;
            }

            /* Assume nothing */
            do_turn = false;
            do_move = false;
            do_view = false;

            /* Assume nothing */
            did_open_door = false;
            did_bash_door = false;

            /* Process moves */
            for (i = 0; i < 5; i++)
            {
                /* Get the direction (or stagger) */
                int d = (stagger ? Misc.ddd[Random.randint0(8)] : mm[i]);

                /* Get the destination */
                ny = oy + Misc.ddy[d];
                nx = ox + Misc.ddx[d];

                /* Floor is open? */
                if (Cave.cave_floor_bold(ny, nx))
                {
                    /* Go ahead and move */
                    do_move = true;
                }

                /* Permanent wall in the way */
                else if (Cave.cave.feat[ny][nx] >= Cave.FEAT_PERM_EXTRA)
                {
                    /* Nothing */
                }

                /* Normal wall, door, or secret door in the way */
                else
                {
                    /* There's some kind of feature in the way, so learn about
                     * kill-wall and pass-wall now
                     */
                    if (m_ptr.ml)
                    {
                        l_ptr.flags.on(Monster_Flag.PASS_WALL.value);
                        l_ptr.flags.on(Monster_Flag.KILL_WALL.value);
                    }

                    /* Monster moves through walls (and doors) */
                    if (r_ptr.flags.has(Monster_Flag.PASS_WALL.value))
                    {
                        /* Pass through walls/doors/rubble */
                        do_move = true;
                    }

                    /* Monster destroys walls (and doors) */
                    else if (r_ptr.flags.has(Monster_Flag.KILL_WALL.value))
                    {
                        /* Eat through walls/doors/rubble */
                        do_move = true;

                        /* Forget the wall */
                        Cave.cave.info[ny][nx] &= ~(Cave.CAVE_MARK);

                        /* Notice */
                        Cave.cave_set_feat(c, ny, nx, Cave.FEAT_FLOOR);

                        /* Note changes to viewable region */
                        if (Cave.player_has_los_bold(ny, nx)) do_view = true;
                    }

                    /* Handle doors and secret doors */
                    else if (((Cave.cave.feat[ny][nx] >= Cave.FEAT_DOOR_HEAD) &&
                                 (Cave.cave.feat[ny][nx] <= Cave.FEAT_DOOR_TAIL)) ||
                                (Cave.cave.feat[ny][nx] == Cave.FEAT_SECRET))
                    {
                        bool may_bash = true;

                        /* Take a turn */
                        do_turn = true;

                        /* Learn about door abilities */
                        if (m_ptr.ml)
                        {
                            l_ptr.flags.on(Monster_Flag.OPEN_DOOR.value);
                            l_ptr.flags.on(Monster_Flag.BASH_DOOR.value);
                        }

                        /* Creature can open doors. */
                        if (r_ptr.flags.has(Monster_Flag.OPEN_DOOR.value))
                        {
                            /* Closed doors and secret doors */
                            if ((Cave.cave.feat[ny][nx] == Cave.FEAT_DOOR_HEAD) ||
                                     (Cave.cave.feat[ny][nx] == Cave.FEAT_SECRET)) {
                                /* The door is open */
                                did_open_door = true;

                                /* Do not bash the door */
                                may_bash = false;
                            }

                            /* Locked doors (not jammed) */
                            else if (Cave.cave.feat[ny][nx] < Cave.FEAT_DOOR_HEAD + 0x08) {
                                int k;

                                /* Door power */
                                k = ((Cave.cave.feat[ny][nx] - Cave.FEAT_DOOR_HEAD) & 0x07);

                                /* Try to unlock it */
                                if (Random.randint0(m_ptr.hp / 10) > k) {
                                    Utilities.msg("Something fiddles with a lock.");

                                    /* Reduce the power of the door by one */
                                    Cave.cave_set_feat(c, ny, nx, Cave.cave.feat[ny][nx] - 1);

                                    /* Do not bash the door */
                                    may_bash = false;
                                }
                            }
                        }

                        /* Stuck doors -- attempt to bash them down if allowed */
                        if (may_bash && r_ptr.flags.has(Monster_Flag.BASH_DOOR.value))
                        {
                            int k;

                            /* Door power */
                            k = ((Cave.cave.feat[ny][nx] - Cave.FEAT_DOOR_HEAD) & 0x07);

                            /* Attempt to bash */
                            if (Random.randint0(m_ptr.hp / 10) > k) {
                                Utilities.msg("Something slams against a door.");

                                /* Reduce the power of the door by one */
                                Cave.cave_set_feat(c, ny, nx, Cave.cave.feat[ny][nx] - 1);

                                /* If the door is no longer jammed */
                                if (Cave.cave.feat[ny][nx] < Cave.FEAT_DOOR_HEAD + 0x09)	{
                                    Utilities.msg("You hear a door burst open!");

                                    /* Disturb (sometimes) */
                                    Cave.disturb(Misc.p_ptr, 0, 0);

                                    /* The door was bashed open */
                                    did_bash_door = true;

                                    /* Hack -- fall into doorway */
                                    do_move = true;
                                }
                            }
                        }
                    }

                    /* Deal with doors in the way */
                    if (did_open_door || did_bash_door)
                    {
                        /* Break down the door */
                        if (did_bash_door && (Random.randint0(100) < 50))
                        {
                            Cave.cave_set_feat(c, ny, nx, Cave.FEAT_BROKEN);
                        }

                        /* Open the door */
                        else
                        {
                            Cave.cave_set_feat(c, ny, nx, Cave.FEAT_OPEN);
                        }

                        /* Handle viewable doors */
                        if (Cave.player_has_los_bold(ny, nx)) do_view = true;
                    }
                }

                /* Hack -- check for Glyph of Warding */
                if (do_move && (Cave.cave.feat[ny][nx] == Cave.FEAT_GLYPH))
                {
                    /* Assume no move allowed */
                    do_move = false;

                    /* Break the ward */
                    if (Random.randint1(Misc.BREAK_GLYPH) < r_ptr.level)
                    {
                        /* Describe observable breakage */
                        if ((Cave.cave.info[ny][nx] & (Cave.CAVE_MARK)) != 0)
                        {
                            Utilities.msg("The rune of protection is broken!");
                        }

                        /* Forget the rune */
                        Cave.cave.info[ny][nx] &= ~Cave.CAVE_MARK;

                        /* Break the rune */
                        Cave.cave_set_feat(c, ny, nx, Cave.FEAT_FLOOR);

                        /* Allow movement */
                        do_move = true;
                    }
                }

                /* The player is in the way. */
                if (do_move && (Cave.cave.m_idx[ny][nx] < 0))
                {
                    /* Learn about if the monster attacks */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.NEVER_BLOW.value);

                    /* Some monsters never attack */
                    if (r_ptr.flags.has(Monster_Flag.NEVER_BLOW.value))
                    {
                        /* Do not move */
                        do_move = false;
                    }

                    /* Otherwise, attack the player */
                    else
                    {
                        /* Do the attack */
                        m_ptr.make_attack_normal(Misc.p_ptr);

                        /* Do not move */
                        do_move = false;

                        /* Took a turn */
                        do_turn = true;
                    }
                }

                /* Some monsters never move */
                if (do_move && r_ptr.flags.has(Monster_Flag.NEVER_MOVE.value))
                {
                    /* Learn about lack of movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.NEVER_MOVE.value);

                    /* Do not move */
                    do_move = false;
                }

                /* A monster is in the way */
                if (do_move && (Cave.cave.m_idx[ny][nx] > 0))
                {
                    Monster n_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[ny][nx]);

                    /* Kill weaker monsters */
                    bool kill_ok = r_ptr.flags.has(Monster_Flag.KILL_BODY.value);

                    /* Move weaker monsters if they can swap places */
                    /* (not in a wall) */
                    bool move_ok = (r_ptr.flags.has(Monster_Flag.MOVE_BODY.value) &&
                                   Cave.cave_floor_bold(m_ptr.fy, m_ptr.fx));

                    /* Assume no movement */
                    do_move = false;

                    if (compare_monsters(m_ptr, n_ptr) > 0)
                    {
                        /* Learn about pushing and shoving */
                        if (m_ptr.ml)
                        {
                            l_ptr.flags.on(Monster_Flag.KILL_BODY.value);
                            l_ptr.flags.on(Monster_Flag.MOVE_BODY.value);
                        }

                        if (kill_ok || move_ok)
                        {
                            /* Get the names of the monsters involved */
                            //char m_name[80];
                            //char n_name[80];
                            string m_name;
                            string n_name;
                            m_name = m_ptr.monster_desc(Desc.IND1);
                            n_name = n_ptr.monster_desc(Desc.IND1);

                            /* Allow movement */
                            do_move = true;

                            /* Monster ate another monster */
                            if (kill_ok)
                            {
                                /* Note if visible */
                                if (m_ptr.ml && (m_ptr.mflag & (Monster_Flag.MFLAG_VIEW)) != 0)
                                {
                                    string name = Char.ToUpper(m_name[0]) + m_name.Substring(1);
                                    Utilities.msg("{0} tramples over {1}.", name, n_name);
                                }

                                throw new NotImplementedException();
                                //delete_monster(ny, nx);
                            }
                            else
                            {
                                /* Note if visible */
                                if (m_ptr.ml && (m_ptr.mflag & (Monster_Flag.MFLAG_VIEW)) != 0)
                                {
                                    string name = Char.ToUpper(m_name[0]) + m_name.Substring(1);
                                    Utilities.msg("{0} pushes past {1}.", name, n_name);
                                }
                            }
                        }
                    }
                }

                /* Creature has been allowed move */
                if (do_move)
                {
                    short this_o_idx, next_o_idx = 0;

                    /* Learn about no lack of movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.NEVER_MOVE.value);

                    /* Take a turn */
                    do_turn = true;

                    /* Move the monster */
                    monster_swap(oy, ox, ny, nx);

                    /* Possible disturb */
                    if (m_ptr.ml && (Option.disturb_move.value ||
                                (((m_ptr.mflag & (Monster_Flag.MFLAG_VIEW)) != 0) && Option.disturb_near.value)))
                    {
                        /* Disturb */
                        Cave.disturb(Misc.p_ptr, 0, 0);
                    }

                    /* Scan all objects in the grid */
                    for (this_o_idx = Cave.cave.o_idx[ny][nx]; this_o_idx != 0; this_o_idx = next_o_idx)
                    {
                        Object.Object o_ptr;

                        /* Get the object */
                        o_ptr = Object.Object.byid(this_o_idx);
                        if(o_ptr == null)
                            continue;

                        /* Get the next object */
                        next_o_idx = o_ptr.next_o_idx;

                        /* Skip gold */
                        if (o_ptr.tval == TVal.TV_GOLD) continue;

                        /* Learn about item pickup behavior */
                        if (m_ptr.ml)
                        {
                            l_ptr.flags.on(Monster_Flag.TAKE_ITEM.value);
                            l_ptr.flags.on(Monster_Flag.KILL_ITEM.value);
                        }

                        /* Take or Kill objects on the floor */
                        if (r_ptr.flags.has(Monster_Flag.TAKE_ITEM.value) || r_ptr.flags.has(Monster_Flag.KILL_ITEM.value))
                        {
                            Bitflag obj_flags = new Bitflag(Object_Flag.SIZE);
                            Bitflag mon_flags = new Bitflag(Monster_Flag.SIZE);

                            //char m_name[80];
                            //char o_name[80];
                            string m_name;
                            string o_name = "";

                            mon_flags.wipe();

                            /* Extract some flags */
                            o_ptr.object_flags(ref obj_flags);

                            /* Get the object name */
                            o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);

                            /* Get the monster name */
                            m_name = m_ptr.monster_desc(Desc.IND1);

                            /* React to objects that hurt the monster */
                            throw new NotImplementedException();
                            //react_to_slay(obj_flags, mon_flags);

                            ///* The object cannot be picked up by the monster */
                            //if (o_ptr.artifact || rf_is_inter(r_ptr.flags, mon_flags))
                            //{
                            //    /* Only give a message for "take_item" */
                            //    if (rf_has(r_ptr.flags, RF_TAKE_ITEM))
                            //    {
                            //        /* Describe observable situations */
                            //        if (m_ptr.ml && Cave.player_has_los_bold(ny, nx) && !squelch_item_ok(o_ptr))
                            //        {
                            //            /* Dump a message */
                            //            msg("%^s tries to pick up %s, but fails.",
                            //                       m_name, o_name);
                            //        }
                            //    }
                            //}

                            ///* Pick up the item */
                            //else if (rf_has(r_ptr.flags, RF_TAKE_ITEM))
                            //{
                            //    Object.Object i_ptr;
                            //    //object_type object_type_body;

                            //    /* Describe observable situations */
                            //    if (player_has_los_bold(ny, nx) && !squelch_item_ok(o_ptr))
                            //    {
                            //        /* Dump a message */
                            //        msg("%^s picks up %s.", m_name, o_name);
                            //    }

                            //    /* Get local object */
                            //    i_ptr = &object_type_body;

                            //    /* Obtain local object */
                            //    object_copy(i_ptr, o_ptr);

                            //    /* Delete the object */
                            //    delete_object_idx(this_o_idx);

                            //    /* Carry the object */
                            //    monster_carry(m_ptr, i_ptr);
                            //}

                            ///* Destroy the item */
                            //else
                            //{
                            //    /* Describe observable situations */
                            //    if (player_has_los_bold(ny, nx) && !squelch_item_ok(o_ptr))
                            //    {
                            //        /* Dump a message */
                            //        msgt(MSG_DESTROY, "%^s crushes %s.", m_name, o_name);
                            //    }

                            //    /* Delete the object */
                            //    delete_object_idx(this_o_idx);
                            //}
                        }
                    }
                }

                /* Stop when done */
                if (do_turn) break;
            }

            /* If we haven't done anything, try casting a spell again */
            if (Option.birth_ai_smart.value && !do_turn && !do_move)
            {
                /* Cast spell */
                if (make_attack_spell(m_idx)) return;
            }

            if (r_ptr.flags.has(Monster_Flag.HAS_LIGHT.value)) do_view = true;

            /* Notice changes in view */
            if (do_view)
            {
                /* Update the visuals */
                Misc.p_ptr.update |= (Misc.PU_UPDATE_VIEW | Misc.PU_MONSTERS);

                /* Fully update the flow XXX XXX XXX */
                Misc.p_ptr.update |= (Misc.PU_FORGET_FLOW | Misc.PU_UPDATE_FLOW);
            }

            /* Hack -- get "bold" if out of options */
            if (!do_turn && !do_move && m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] != 0)
            {
                mon_clear_timed(m_idx, Misc.MON_TMD.FEAR, Misc.MON_TMD_FLG_NOTIFY, false);
            }

            /* If we see an unaware monster do something, become aware of it */
            if(do_turn && m_ptr.unaware) {
                throw new NotImplementedException();
                //become_aware(m_idx);
            }
        }
示例#31
0
        /**
         * Log the names of a flagset to a file.
         *
         * \param f is the set of flags we are logging.
         * \param log_file is the file to which we are logging the names.
         */
        //log_file was type ang_file... I don't think we need that anymore...
        public static void log_flags(Bitflag f, FileStream log_file)
        {
            throw new NotImplementedException();
            //int i;

            //file_putf(log_file, "Object flags are:\n");
            //for (i = 0; i < OF_MAX; i++)
            //    if (of_has(f, i))
            //        file_putf(log_file, "%s\n", flag_names[i]);
        }
示例#32
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;
        }
示例#33
0
        /*
         * Calculate maximum mana.  You do not need to know any spells.
         * Note that mana is lowered by heavy (or inappropriate) armor.
         *
         * This function induces status messages.
         */
        static void calc_mana()
        {
            int msp, levels, cur_wgt, max_wgt;

            Object.Object o_ptr;

            bool old_cumber_glove = instance.cumber_glove;
            bool old_cumber_armor = instance.cumber_armor;

            /* Hack -- Must be literate */
            if (instance.Class.spell_book == 0)
            {
                instance.msp = 0;
                instance.csp = 0;
                instance.csp_frac = 0;
                return;
            }

            /* Extract "effective" player level */
            levels = (instance.lev - instance.Class.spell_first) + 1;
            if (levels > 0)
            {
                msp = 1;
                msp += (short)(adj_mag_mana[instance.state.stat_ind[instance.Class.spell_stat]] * levels / 100);
            }
            else
            {
                levels = 0;
                msp = 0;
            }

            /* Process gloves for those disturbed by them */
            if (instance.player_has(Misc.PF.CUMBER_GLOVE.value))
            {
                Bitflag f = new Bitflag(Object_Flag.SIZE);

                /* Assume player is not encumbered by gloves */
                instance.cumber_glove = false;

                /* Get the gloves */
                o_ptr = instance.inventory[Misc.INVEN_HANDS];

                /* Examine the gloves */
                o_ptr.object_flags(ref f);

                /* Normal gloves hurt mage-type spells */
                if (o_ptr.kind != null && !f.has(Object_Flag.FREE_ACT.value) &&
                    !f.has(Object_Flag.SPELLS_OK.value) && !(f.has(Object_Flag.DEX.value) &&
                    (o_ptr.pval[o_ptr.which_pval(Object_Flag.DEX.value)] > 0)))
                {
                    /* Encumbered */
                    instance.cumber_glove = true;

                    /* Reduce mana */
                    msp = (3 * msp) / 4;
                }
            }

            /* Assume player not encumbered by armor */
            instance.cumber_armor = false;

            /* Weigh the armor */
            cur_wgt = 0;
            cur_wgt += instance.inventory[Misc.INVEN_BODY].weight;
            cur_wgt += instance.inventory[Misc.INVEN_HEAD].weight;
            cur_wgt += instance.inventory[Misc.INVEN_ARM].weight;
            cur_wgt += instance.inventory[Misc.INVEN_OUTER].weight;
            cur_wgt += instance.inventory[Misc.INVEN_HANDS].weight;
            cur_wgt += instance.inventory[Misc.INVEN_FEET].weight;

            /* Determine the weight allowance */
            max_wgt = instance.Class.spell_weight;

            /* Heavy armor penalizes mana */
            if (((cur_wgt - max_wgt) / 10) > 0)
            {
                /* Encumbered */
                instance.cumber_armor = true;

                /* Reduce mana */
                msp -= ((cur_wgt - max_wgt) / 10);
            }

            /* Mana can never be negative */
            if (msp < 0) msp = 0;

            /* Maximum mana has changed */
            if (msp != instance.msp)
            {
                /* Save new limit */
                instance.msp = (short)msp;

                /* Enforce new limit */
                if (instance.csp >= msp)
                {
                    instance.csp = (short)msp;
                    instance.csp_frac = 0;
                }

                /* Display mana later */
                instance.redraw |= (Misc.PR_MANA);
            }

            /* Hack -- handle "xtra" mode */
            if (Misc.character_xtra != 0) return;

            /* Take note when "glove state" changes */
            if (old_cumber_glove != instance.cumber_glove)
            {
                /* Message */
                if (instance.cumber_glove)
                {
                    Utilities.msg("Your covered hands feel unsuitable for spellcasting.");
                }
                else
                {
                    Utilities.msg("Your hands feel more suitable for spellcasting.");
                }
            }

            /* Take note when "armor state" changes */
            if (old_cumber_armor != instance.cumber_armor)
            {
                /* Message */
                if (instance.cumber_armor)
                {
                    Utilities.msg("The weight of your armor encumbers your movement.");
                }
                else
                {
                    Utilities.msg("You feel able to move more freely.");
                }
            }
        }
示例#34
0
        /*
         * Notice a set of flags - returns true if anything new was learned
         */
        bool notice_flags(Bitflag flags)
        {
            throw new NotImplementedException();
            //if (!of_is_subset(o_ptr.known_flags, flags))
            //{
            //    of_union(o_ptr.known_flags, flags);
            //    /* XXX Eddie don't want infinite recursion if object_check_for_ident sets more flags,
            //     * but maybe this will interfere with savefile repair
            //     */
            //    object_check_for_ident(o_ptr);
            //    event_signal(EVENT_INVENTORY);
            //    event_signal(EVENT_EQUIPMENT);

            //    return true;
            //}

            //return false;
        }
示例#35
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;
        }
示例#36
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);
        }
示例#37
0
        /**
         * Return the pval_flags for an item
         */
        public void object_pval_flags(out Bitflag[] flags)
        {
            flags = new Bitflag[Misc.MAX_PVALS];

            if (this.kind == null)
                return;

            for (int i = 0; i < Misc.MAX_PVALS; i++) {
                flags[i] = new Bitflag(Object_Flag.SIZE);
                flags[i].copy(pval_flags[i]);
            }
        }
示例#38
0
        /*
         * Obtain the flags for an item which are known to the player
         */
        public void object_flags_known(ref Bitflag flags)
        {
            object_flags(ref flags);

            flags.inter(known_flags);

            if (flavor_is_aware())
                flags.union(kind.flags);

            if (ego != null && easy_know())
                flags.union(ego.flags);
        }
示例#39
0
        static int obj_desc_pval(Object o_ptr, string buf, int max, int end, bool spoil)
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);
            int i;

            o_ptr.object_flags(ref f);
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.PVAL, Object_Flag.object_flag_type.STAT);

            if (!f.is_inter(f2)) return end;

            buf += " <";
            //strnfcat(buf, max, &end, " <");
            for (i = 0; i < o_ptr.num_pvals; i++) {
                if (spoil || o_ptr.this_pval_is_visible(i)) {
                    if(i > 0) {
                        buf += ", ";
                        //strnfcat(buf, max, &end, ", ");
                    }
                    buf += o_ptr.pval[i] > 0 ? "+" + o_ptr.pval[i] : o_ptr.pval[i].ToString();
                    //strnfcat(buf, max, &end, "%+d", o_ptr.pval[i]);
                }
            }

            buf += ">";
            end = buf.Length; //f**k it.
            //strnfcat(buf, max, &end, ">");

            return end;
        }
示例#40
0
        /*
         * Have a monster choose a spell to cast.
         *
         * Note that the monster's spell list has already had "useless" spells
         * (bolts that won't hit the player, summons without room, etc.) removed.
         * Perhaps that should be done by this function.
         *
         * Stupid monsters will just pick a spell randomly.  Smart monsters
         * will choose more "intelligently".
         *
         * This function could be an efficiency bottleneck.
         */
        static int choose_attack_spell(int m_idx, Bitflag f)
        {
            throw new NotImplementedException();
            //monster_type *m_ptr = cave_monster(cave, m_idx);
            //monster_race *r_ptr = &r_info[m_ptr.r_idx];

            //int num = 0;
            //byte spells[RSF_MAX];

            //int i, py = p_ptr.py, px = p_ptr.px;

            //bool has_escape, has_attack, has_summon, has_tactic;
            //bool has_annoy, has_haste, has_heal;


            ///* Smart monsters restrict their spell choices. */
            //if (OPT(birth_ai_smart) && !rf_has(r_ptr.flags, RF_STUPID))
            //{
            //    /* What have we got? */
            //    has_escape = test_spells(f, RST_ESCAPE);
            //    has_attack = test_spells(f, RST_ATTACK | RST_BOLT | RST_BALL | RST_BREATH);
            //    has_summon = test_spells(f, RST_SUMMON);
            //    has_tactic = test_spells(f, RST_TACTIC);
            //    has_annoy = test_spells(f, RST_ANNOY);
            //    has_haste = test_spells(f, RST_HASTE);
            //    has_heal = test_spells(f, RST_HEAL);

            //    /*** Try to pick an appropriate spell type ***/

            //    /* Hurt badly or afraid, attempt to flee */
            //    if (has_escape && ((m_ptr.hp < m_ptr.maxhp / 4) || m_ptr.m_timed[MON_TMD_FEAR]))
            //    {
            //        /* Choose escape spell */
            //        set_spells(f, RST_ESCAPE);
            //    }

            //    /* Still hurt badly, couldn't flee, attempt to heal */
            //    else if (has_heal && m_ptr.hp < m_ptr.maxhp / 4)
            //    {
            //        /* Choose heal spell */
            //        set_spells(f, RST_HEAL);
            //    }

            //    /* Player is close and we have attack spells, blink away */
            //    else if (has_tactic && (distance(py, px, m_ptr.fy, m_ptr.fx) < 4) &&
            //             has_attack && (randint0(100) < 75))
            //    {
            //        /* Choose tactical spell */
            //        set_spells(f, RST_TACTIC);
            //    }

            //    /* We're hurt (not badly), try to heal */
            //    else if (has_heal && (m_ptr.hp < m_ptr.maxhp * 3 / 4) &&
            //             (randint0(100) < 60))
            //    {
            //        /* Choose heal spell */
            //        set_spells(f, RST_HEAL);
            //    }

            //    /* Summon if possible (sometimes) */
            //    else if (has_summon && (randint0(100) < 50))
            //    {
            //        /* Choose summon spell */
            //        set_spells(f, RST_SUMMON);
            //    }

            //    /* Attack spell (most of the time) */
            //    else if (has_attack && (randint0(100) < 85))
            //    {
            //        /* Choose attack spell */
            //        set_spells(f, RST_ATTACK | RST_BOLT | RST_BALL | RST_BREATH);
            //    }

            //    /* Try another tactical spell (sometimes) */
            //    else if (has_tactic && (randint0(100) < 50))
            //    {
            //        /* Choose tactic spell */
            //        set_spells(f, RST_TACTIC);
            //    }

            //    /* Haste self if we aren't already somewhat hasted (rarely) */
            //    else if (has_haste && (randint0(100) < (20 + r_ptr.speed - m_ptr.mspeed)))
            //    {
            //        /* Choose haste spell */
            //        set_spells(f, RST_HASTE);
            //    }

            //    /* Annoy player (most of the time) */
            //    else if (has_annoy && (randint0(100) < 85))
            //    {
            //        /* Choose annoyance spell */
            //        set_spells(f, RST_ANNOY);
            //    }

            //    /* Else choose no spell */
            //    else
            //    {
            //        rsf_wipe(f);
            //    }

            //    /* Anything left? */
            //    if (rsf_is_empty(f)) return (FLAG_END);
            //}

            ///* Extract all spells: "innate", "normal", "bizarre" */
            //for (i = FLAG_START, num = 0; i < RSF_MAX; i++)
            //{
            //    if (rsf_has(f, i)) spells[num++] = i;
            //}

            ///* Paranoia */
            //if (num == 0) return 0;

            ///* Pick at random */
            //return (spells[randint0(num)]);
        }
示例#41
0
        /*
         * Checks for additional knowledge implied by what the player already knows.
         *
         * \param o_ptr is the object to check
         *
         * returns whether it calls object_notice_everyting
         */
        bool check_for_ident()
        {
            Bitflag flags = new Bitflag(Object_Flag.SIZE);
            Bitflag known_flags = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            object_flags(ref flags);
            object_flags_known(ref known_flags);

            /* Some flags are irrelevant or never learned or too hard to learn */
            Object_Flag.create_mask(f2, false,	Object_Flag.object_flag_type.INT,
                                                Object_Flag.object_flag_type.IGNORE,
                                                Object_Flag.object_flag_type.HATES);

            flags.diff(f2);
            known_flags.diff(f2);

            if (!flags.is_equal(known_flags)) return false;

            /* If we know attack bonuses, and defence bonuses, and effect, then
             * we effectively know everything, so mark as such */
            if ((attack_plusses_are_visible() || (was_sensed() && to_h == 0 && to_d == 0)) &&
                (defence_plusses_are_visible() || (was_sensed() && to_a == 0)) &&
                (effect_is_known() || effect() == null))
            {
                /* In addition to knowing the pval flags, it is necessary to know the pvals to know everything */
                int i;
                for (i = 0; i < num_pvals; i++)
                    if (!this_pval_is_visible(i))
                        break;
                if (i == num_pvals) {
                    notice_everything();
                    return true;
                }
            }

            /* We still know all the flags, so we still know if it's an ego */
            if (ego != null)
            {
                /* require worn status so you don't learn launcher of accuracy or gloves of slaying before wield */
                if (was_worn())
                    notice_ego();
            }

            return false;
        }
示例#42
0
        /**
         * Obtain the pval_flags for an item which are known to the player
         */
        public void pval_flags_known(out Bitflag[] flags)
        {
            int i, flag;

            object_pval_flags(out flags);

            for(i = 0; i < Misc.MAX_PVALS; i++) {
                flags[i].inter(known_flags);
            }

            /* Kind and ego pval_flags may have shifted pvals so we iterate */
            if(flavor_is_aware()) {
                for(i = 0; i < Misc.MAX_PVALS; i++) {
                    for(flag = kind.pval_flags[i].next(Bitflag.FLAG_START);
                            flag != Bitflag.FLAG_null; flag = kind.pval_flags[i].next(flag + 1)) {

                        flags[which_pval(flag)].on(flag);
                    }
                }
            }

            if(ego != null && easy_know()) {
                for(i = 0; i < Misc.MAX_PVALS; i++) {
                    for(flag = ego.pval_flags[i].next(Bitflag.FLAG_START);
                            flag != Bitflag.FLAG_null; flag = ego.pval_flags[i].next(flag + 1)) {

                        flags[which_pval(flag)].on(flag);
                    }
                }
            }
        }
示例#43
0
        /**
         * Notice curses on an object.
         *
         * \param o_ptr is the object to notice curses on
         */
        bool notice_curses()
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            object_flags(ref f);

            /* Gather whatever curse flags there are to know */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.CURSE);

            /* Remove everything except the curse flags */
            f.inter(f2);

            /* give knowledge of which curses are present */
            notice_flags(f);

            check_for_ident();

            Misc.p_ptr.notice |= Misc.PN_SQUELCH;

            return !f.is_empty();
        }
示例#44
0
        /**
         * \returns whether a specific pval is known to the player
         */
        public bool this_pval_is_visible(int pval)
        {
            Bitflag[] f = new Bitflag[Misc.MAX_PVALS];
            //for (int i = 0; i < f.Length; i++){ //We use f for an outtype, no need to initialize
            //    f[i] = new Bitflag(Object_Flag.SIZE);
            //}
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            Misc.assert(kind != null);

            if ((ident & IDENT_STORE) != 0)
                return true;

            /* Aware jewelry with non-variable pval */
            if (is_jewelry() && flavor_is_aware()) {
                if (!Random.randcalc_varies(kind.pval[pval]))
                    return true;
            }

            if (was_worn()) {
                pval_flags_known(out f);

                /* Create the mask for pval-related flags */
                Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.STAT, Object_Flag.object_flag_type.PVAL);

                if (f[pval].is_inter(f2))
                    return true;
            }

            return false;
        }
示例#45
0
        /*
         * Calculate and set the current light radius.
         *
         * The brightest wielded object counts as the light source; radii do not add
         * up anymore.
         *
         * Note that a cursed light source no longer emits light.
         */
        void calc_torch()
        {
            int i;

            short old_light = cur_light;
            bool burn_light = true;

            short new_light = 0;
            int extra_light = 0;

            /* Ascertain lightness if in the town */
            if (depth == 0 && ((Misc.turn % (10L * Cave.TOWN_DAWN)) < ((10L * Cave.TOWN_DAWN) / 2)))
                burn_light = false;

            /* Examine all wielded objects, use the brightest */
            for (i = Misc.INVEN_WIELD; i < Misc.INVEN_TOTAL; i++)
            {
                Bitflag f = new Bitflag(Object_Flag.SIZE);

                int amt = 0;
                Object.Object o_ptr = inventory[i];

                /* Skip empty slots */
                if (o_ptr.kind == null) continue;

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

                /* Cursed objects emit no light */
                if (f.has(Object_Flag.LIGHT_CURSE.value))
                    amt = 0;

                /* Examine actual lights */
                else if (o_ptr.tval == TVal.TV_LIGHT)
                {
                    int flag_inc = f.has(Object_Flag.LIGHT.value) ? 1 : 0;

                    /* Artifact lights provide permanent bright light */
                    if (o_ptr.artifact != null)
                        amt = 3 + flag_inc;

                    /* Non-artifact lights and those without fuel provide no light */
                    else if (!burn_light || o_ptr.timeout == 0)
                        amt = 0;

                    /* All lit lights provide at least radius 2 light */
                    else
                    {
                        amt = 2 + flag_inc;

                        /* Torches below half fuel provide less light */
                        if (o_ptr.sval == SVal.SV_LIGHT_TORCH && o_ptr.timeout < (Misc.FUEL_TORCH / 4)) //Nick: This looks like 1/4th...
                            amt--;
                    }
                }

                else
                {
                    /* LIGHT flag on an non-cursed non-lights always increases radius */
                    if (f.has(Object_Flag.LIGHT.value)) extra_light++;
                }

                /* Alter cur_light if reasonable */
                if (new_light < amt)
                    new_light = (short)amt;
            }

            /* Add bonus from LIGHT flags */
            new_light += (short)extra_light;

            /* Limit light */
            new_light = (short)Math.Min((int)new_light, 5);
            new_light = (short)Math.Max((int)new_light, 0);

            /* Notice changes in the "light radius" */
            if (old_light != new_light)
            {
                /* Update the visuals */
                cur_light = new_light;
                update |= (Misc.PU_UPDATE_VIEW | Misc.PU_MONSTERS);
            }
        }
示例#46
0
        /**
         * Add a pval to an object, rearranging flags as necessary. Returns true
         * if the number of pvals is now different, false if it is the same.
         *
         * \param o_ptr is the object we're adjusting
         * \param pval is the pval we are adding
         * \param flag is the flag to which we are adding the pval
         */
        bool add_pval(int pval, int flag)
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            int a = -1, best_pval;

            /* Sanity check (we may be called with 0 - see ticket #1451) */
            if (pval == 0) return false;

            Object_Flag.create_mask(f, false, Object_Flag.object_flag_type.PVAL, Object_Flag.object_flag_type.STAT);

            if (flags.has(flag)) {
                /* See if any other flags are associated with this pval */
                a = which_pval(flag);
                f.off(flag);
                f.inter(pval_flags[a]);
                if (f.is_empty()) { /* Safe to increment and finish */
                    this.pval[a] += (short)pval;
                    if (this.pval[a] == 0) { /* Remove the flag */
                        flags.off(flag);
                        pval_flags[a].off(flag);
                    }
                    return (object_dedup_pvals());
                }
            }

            /* So it doesn't have the flag, or it does but that pval also has others */

            /* Create a new pval if we can */
            if (this.num_pvals < Misc.MAX_PVALS) {
                this.pval[this.num_pvals] = (short)pval;
                this.pval_flags[this.num_pvals].on(flag);
                if (a != -1) { /* then we need to move the flag to the new pval */
                    this.pval[this.num_pvals] += this.pval[a];
                    this.pval_flags[a].off(flag);
                } else /* We need to add it to object_flags */
                    this.flags.on(flag);
                this.num_pvals++; /* We do this last because pvals start from zero */
                /* We invert the logic because we've already added a pval */
                return (!object_dedup_pvals());
            } else { /* we use the closest existing pval */
                best_pval = object_closest_pval((pval + (a == -1 ? 0 : this.pval[a])));
                if (best_pval != a) { /* turn on the flag on the new pval */
                    this.pval_flags[best_pval].on(flag);
                    if(a != -1) /* turn it off on its old pval */
                        this.pval_flags[a].off(flag);
                    else /* add it to object_flags */
                        this.flags.on(flag);
                }
                return false; /* We haven't changed any pvals, so no need to de-dup */
            }
        }
示例#47
0
        /*
         * Calculate the players current "state", taking into account
         * not only race/class intrinsics, but also objects being worn
         * and temporary spell effects.
         *
         * See also calc_mana() and calc_hitpoints().
         *
         * Take note of the new "speed code", in particular, a very strong
         * player will start slowing down as soon as he reaches 150 pounds,
         * but not until he reaches 450 pounds will he be half as fast as
         * a normal kobold.  This both hurts and helps the player, hurts
         * because in the old days a player could just avoid 300 pounds,
         * and helps because now carrying 300 pounds is not very painful.
         *
         * The "weapon" and "bow" do *not* add to the bonuses to hit or to
         * damage, since that would affect non-combat things.  These values
         * are actually added in later, at the appropriate place.
         *
         * If id_only is true, calc_bonuses() will only use the known
         * information of objects; thus it returns what the player _knows_
         * the character state to be.
         */
        void calc_bonuses(Object.Object[] inventory, ref Player_State state, bool id_only)
        {
            Player p_ptr = Player.instance;
            int i, j, hold;

            int extra_blows = 0;
            int extra_shots = 0;
            int extra_might = 0;

            Object.Object o_ptr;

            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag collect_f = new Bitflag(Object_Flag.SIZE);

            /*** Reset ***/
            state = new Player_State();
            //memset(state, 0, sizeof *state);

            /* Set various defaults */
            state.speed = 110;
            state.num_blows = 100;

            /*** Extract race/class info ***/

            /* Base infravision (purely racial) */
            if(p_ptr.Race == null)
                return;
            state.see_infra = p_ptr.Race.infra;

            /* Base skills */
            for (i = 0; i < (int)Skill.MAX; i++)
                state.skills[i] = (short)(p_ptr.Race.r_skills[i] + p_ptr.Class.c_skills[i]);

            /*** Analyze player ***/

            /* Extract the player flags */
            Player.player_flags(ref collect_f);

            /*** Analyze equipment ***/

            /* Scan the equipment */
            for (i = Misc.INVEN_WIELD; i < Misc.INVEN_TOTAL; i++)
            {
                o_ptr = inventory[i];

                /* Skip non-objects */
                if (o_ptr ==  null || o_ptr.kind == null) continue;

                /* Extract the item flags */
                if (id_only)
                    o_ptr.object_flags_known(ref f);
                else
                    o_ptr.object_flags(ref f);

                collect_f.union(f);

                /* Affect stats */
                if (f.has(Object_Flag.STR.value)) state.stat_add[(int)Stat.Str] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.STR.value)];
                if (f.has(Object_Flag.INT.value)) state.stat_add[(int)Stat.Int] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.INT.value)];
                if (f.has(Object_Flag.WIS.value)) state.stat_add[(int)Stat.Wis] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.WIS.value)];
                if (f.has(Object_Flag.DEX.value)) state.stat_add[(int)Stat.Dex] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.DEX.value)];
                if (f.has(Object_Flag.CON.value)) state.stat_add[(int)Stat.Con] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.CON.value)];
                if (f.has(Object_Flag.CHR.value)) state.stat_add[(int)Stat.Chr] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.CHR.value)];

                /* Affect stealth */
                if (f.has(Object_Flag.STEALTH.value)) state.skills[(int)Skill.STEALTH] +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.STEALTH.value)];

                /* Affect searching ability (factor of five) */
                if (f.has(Object_Flag.SEARCH.value)) state.skills[(int)Skill.SEARCH] +=
                    (short)(o_ptr.pval[o_ptr.which_pval(Object_Flag.SEARCH.value)] * 5);

                /* Affect searching frequency (factor of five) */
                if (f.has(Object_Flag.SEARCH.value)) state.skills[(int)Skill.SEARCH_FREQUENCY] +=
                    (short)(o_ptr.pval[o_ptr.which_pval(Object_Flag.SEARCH.value)] * 5);

                /* Affect infravision */
                if (f.has(Object_Flag.INFRA.value)) state.see_infra +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.INFRA.value)];

                /* Affect digging (factor of 20) */
                if (f.has(Object_Flag.TUNNEL.value)) state.skills[(int)Skill.DIGGING] +=
                    (short)(o_ptr.pval[o_ptr.which_pval(Object_Flag.TUNNEL.value)] * 20);

                /* Affect speed */
                if (f.has(Object_Flag.SPEED.value)) state.speed +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.SPEED.value)];

                /* Affect blows */
                if (f.has(Object_Flag.BLOWS.value)) extra_blows +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.BLOWS.value)];

                /* Affect shots */
                if (f.has(Object_Flag.SHOTS.value)) extra_shots +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.SHOTS.value)];

                /* Affect Might */
                if (f.has(Object_Flag.MIGHT.value)) extra_might +=
                    o_ptr.pval[o_ptr.which_pval(Object_Flag.MIGHT.value)];

                /* Modify the base armor class */
                state.ac += o_ptr.ac;

                /* The base armor class is always known */
                state.dis_ac += o_ptr.ac;

                /* Apply the bonuses to armor class */
                if (!id_only || o_ptr.is_known())
                    state.to_a += o_ptr.to_a;

                /* Apply the mental bonuses to armor class, if known */
                if (o_ptr.defence_plusses_are_visible())
                    state.dis_to_a += o_ptr.to_a;

                /* Hack -- do not apply "weapon" bonuses */
                if (i == Misc.INVEN_WIELD) continue;

                /* Hack -- do not apply "bow" bonuses */
                if (i == Misc.INVEN_BOW) continue;

                /* Apply the bonuses to hit/damage */
                if (!id_only || o_ptr.is_known())
                {
                    state.to_h += o_ptr.to_h;
                    state.to_d += o_ptr.to_d;
                }

                /* Apply the mental bonuses tp hit/damage, if known */
                if (o_ptr.attack_plusses_are_visible())
                {
                    state.dis_to_h += o_ptr.to_h;
                    state.dis_to_d += o_ptr.to_d;
                }
            }

            /*** Update all flags ***/

            for (i = 0; i < Object_Flag.MAX.value; i++)
                if (collect_f.has(i))
                    state.flags.on(i);

            /*** Handle stats ***/

            /* Calculate stats */
            for (i = 0; i < (int)Stat.Max; i++)
            {
                int add, top, use, ind;

                /* Extract modifier */
                add = state.stat_add[i];

                /* Maximize mode */
                if (Option.birth_maximize.value)
                {
                    /* Modify the stats for race/class */
                    add += (p_ptr.Race.r_adj[i] + p_ptr.Class.c_adj[i]);
                }

                /* Extract the new "stat_top" value for the stat */
                top = Birther.modify_stat_value(p_ptr.stat_max[i], add);

                /* Save the new value */
                state.stat_top[i] = (short)top;

                /* Extract the new "stat_use" value for the stat */
                use = Birther.modify_stat_value(p_ptr.stat_cur[i], add);

                /* Save the new value */
                state.stat_use[i] = (short)use;

                /* Values: n/a */
                if (use <= 3) ind = 0;

                /* Values: 3, 4, ..., 18 */
                else if (use <= 18) ind = (use - 3);

                /* Ranges: 18/00-18/09, ..., 18/210-18/219 */
                else if (use <= 18+219) ind = (15 + (use - 18) / 10);

                /* Range: 18/220+ */
                else ind = (37);

                Misc.assert((0 <= ind) && (ind < Misc.STAT_RANGE));

                /* Save the new index */
                state.stat_ind[i] = (short)ind;
            }

            /*** Temporary flags ***/

            /* Apply temporary "stun" */
            if (p_ptr.timed[(int)Timed_Effect.STUN] > 50)
            {
                state.to_h -= 20;
                state.dis_to_h -= 20;
                state.to_d -= 20;
                state.dis_to_d -= 20;
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 8 / 10);
            }
            else if (p_ptr.timed[(int)Timed_Effect.STUN] != 0)
            {
                state.to_h -= 5;
                state.dis_to_h -= 5;
                state.to_d -= 5;
                state.dis_to_d -= 5;
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 9 / 10);
            }

            /* Invulnerability */
            if (p_ptr.timed[(int)Timed_Effect.INVULN] != 0)
            {
                state.to_a += 100;
                state.dis_to_a += 100;
            }

            /* Temporary blessing */
            if (p_ptr.timed[(int)Timed_Effect.BLESSED] != 0)
            {
                state.to_a += 5;
                state.dis_to_a += 5;
                state.to_h += 10;
                state.dis_to_h += 10;
                state.skills[(int)Skill.DEVICE] = (short) (state.skills[(int)Skill.DEVICE] * 105 / 100);
            }

            /* Temporary shield */
            if (p_ptr.timed[(int)Timed_Effect.SHIELD] != 0)
            {
                state.to_a += 50;
                state.dis_to_a += 50;
            }

            /* Temporary stoneskin */
            if (p_ptr.timed[(int)Timed_Effect.STONESKIN] != 0)
            {
                state.to_a += 40;
                state.dis_to_a += 40;
                state.speed -= 5;
            }

            /* Temporary "Hero" */
            if (p_ptr.timed[(int)Timed_Effect.HERO] != 0)
            {
                state.to_h += 12;
                state.dis_to_h += 12;
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 105 / 100);
            }

            /* Temporary "Berserk" */
            if (p_ptr.timed[(int)Timed_Effect.SHERO] != 0)
            {
                state.to_h += 24;
                state.dis_to_h += 24;
                state.to_a -= 10;
                state.dis_to_a -= 10;
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 9 / 10);
            }

            /* Temporary "fast" */
            if (p_ptr.timed[(int)Timed_Effect.FAST] != 0 || p_ptr.timed[(int)Timed_Effect.SPRINT] != 0)
                state.speed += 10;

            /* Temporary "slow" */
            if (p_ptr.timed[(int)Timed_Effect.SLOW] != 0)
                state.speed -= 10;

            /* Temporary infravision boost */
            if (p_ptr.timed[(int)Timed_Effect.SINFRA] != 0)
                state.see_infra += 5;

            /* Terror - this is necessary because TMD_AFRAID already occupies the
             * of_ptr.timed slot for Object_Flag.AFRAID */
            if (p_ptr.timed[(int)Timed_Effect.TERROR] > p_ptr.timed[(int)Timed_Effect.AFRAID])
                p_ptr.timed[(int)Timed_Effect.AFRAID] = p_ptr.timed[(int)Timed_Effect.TERROR];

            if (p_ptr.timed[(int)Timed_Effect.TERROR] != 0)
                state.speed += 5;

            /* Fear can come from item flags too */
            if (p_ptr.check_state(Object_Flag.AFRAID, p_ptr.state.flags))
            {
                state.to_h -= 20;
                state.dis_to_h -= 20;
                state.to_a += 8;
                state.dis_to_a += 8;
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 95 / 100);
            }

            /* Confusion */
            if (p_ptr.timed[(int)Timed_Effect.CONFUSED] != 0)
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 75 / 100);

            /* Amnesia */
            if (p_ptr.timed[(int)Timed_Effect.AMNESIA] != 0)
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 8 / 10);

            /* Poison */
            if (p_ptr.timed[(int)Timed_Effect.POISONED] != 0)
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 95 / 100);

            /* Hallucination */
            if (p_ptr.timed[(int)Timed_Effect.IMAGE] != 0)
                state.skills[(int)Skill.DEVICE] = (short)(state.skills[(int)Skill.DEVICE] * 8 / 10);

            /*** Analyze weight ***/

            /* Extract the current weight (in tenth pounds) */
            j = p_ptr.total_weight;

            /* Extract the "weight limit" (in tenth pounds) */
            i = state.weight_limit();

            /* Apply "encumbrance" from weight */
            if (j > i / 2) state.speed -= (short)((j - (i / 2)) / (i / 10));

            /* Bloating slows the player down (a little) */
            if (p_ptr.food >= Misc.PY_FOOD_MAX) state.speed -= 10;

            /* Searching slows the player down */
            if (p_ptr.searching != 0) state.speed -= 10;

            /* Sanity check on extreme speeds */
            if (state.speed < 0) state.speed = 0;
            if (state.speed > 199) state.speed = 199;

            /*** Apply modifier bonuses ***/

            /* Actual Modifier Bonuses (Un-inflate stat bonuses) */
            state.to_a += (short)((int)(adj_dex_ta[state.stat_ind[(int)Stat.Dex]]) - 128);
            state.to_d += (short)((int)(adj_str_td[state.stat_ind[(int)Stat.Str]]) - 128);
            state.to_h += (short)((int)(adj_dex_th[state.stat_ind[(int)Stat.Dex]]) - 128);
            state.to_h += (short)((int)(adj_str_th[state.stat_ind[(int)Stat.Str]]) - 128);

            /* Displayed Modifier Bonuses (Un-inflate stat bonuses) */
            state.dis_to_a += (short)((int)(adj_dex_ta[state.stat_ind[(int)Stat.Dex]]) - 128);
            state.dis_to_d += (short)((int)(adj_str_td[state.stat_ind[(int)Stat.Str]]) - 128);
            state.dis_to_h += (short)((int)(adj_dex_th[state.stat_ind[(int)Stat.Dex]]) - 128);
            state.dis_to_h += (short)((int)(adj_str_th[state.stat_ind[(int)Stat.Str]]) - 128);

            /*** Modify skills ***/

            /* Affect Skill -- stealth (bonus one) */
            state.skills[(int)Skill.STEALTH] += 1;

            /* Affect Skill -- disarming (DEX and INT) */
            state.skills[(int)Skill.DISARM] += adj_dex_dis[state.stat_ind[(int)Stat.Dex]];
            state.skills[(int)Skill.DISARM] += adj_int_dis[state.stat_ind[(int)Stat.Int]];

            /* Affect Skill -- magic devices (INT) */
            state.skills[(int)Skill.DEVICE] += adj_int_dev[state.stat_ind[(int)Stat.Int]];

            /* Affect Skill -- saving throw (WIS) */
            state.skills[(int)Skill.SAVE] += adj_wis_sav[state.stat_ind[(int)Stat.Wis]];

            /* Affect Skill -- digging (STR) */
            state.skills[(int)Skill.DIGGING] += adj_str_dig[state.stat_ind[(int)Stat.Str]];

            /* Affect Skills (Level, by Class) */
            for (i = 0; i < (int)Skill.MAX; i++)
                state.skills[i] += (short)(p_ptr.Class.x_skills[i] * p_ptr.lev / 10);

            /* Limit Skill -- digging from 1 up */
            if (state.skills[(int)Skill.DIGGING] < 1) state.skills[(int)Skill.DIGGING] = 1;

            /* Limit Skill -- stealth from 0 to 30 */
            if (state.skills[(int)Skill.STEALTH] > 30) state.skills[(int)Skill.STEALTH] = 30;
            if (state.skills[(int)Skill.STEALTH] < 0) state.skills[(int)Skill.STEALTH] = 0;

            /* Apply Skill -- Extract noise from stealth */
            state.noise = (uint)(1L << (30 - state.skills[(int)Skill.STEALTH]));

            /* Obtain the "hold" value */
            hold = adj_str_hold[state.stat_ind[(int)Stat.Str]];

            /*** Analyze current bow ***/

            /* Examine the "current bow" */
            o_ptr = inventory[Misc.INVEN_BOW];

            /* Assume not heavy */
            state.heavy_shoot = false;

            /* It is hard to hold a heavy bow */
            if (hold < o_ptr.weight / 10)
            {
                /* Hard to wield a heavy bow */
                state.to_h += (short)(2 * (hold - o_ptr.weight / 10));
                state.dis_to_h += (short)(2 * (hold - o_ptr.weight / 10));

                /* Heavy Bow */
                state.heavy_shoot = true;
            }

            /* Analyze launcher */
            if (o_ptr.kind != null)
            {
                /* Get to shoot */
                state.num_shots = 1;

                /* Analyze the launcher */
                switch (o_ptr.sval)
                {
                    /* Sling and ammo */
                    case SVal.SV_SLING:
                    {
                        state.ammo_tval = TVal.TV_SHOT;
                        state.ammo_mult = 2;
                        break;
                    }

                    /* Short Bow and Arrow */
                    case SVal.SV_SHORT_BOW:
                    {
                        state.ammo_tval = TVal.TV_ARROW;
                        state.ammo_mult = 2;
                        break;
                    }

                    /* Long Bow and Arrow */
                    case SVal.SV_LONG_BOW:
                    {
                        state.ammo_tval = TVal.TV_ARROW;
                        state.ammo_mult = 3;
                        break;
                    }

                    /* Light Crossbow and Bolt */
                    case SVal.SV_LIGHT_XBOW:
                    {
                        state.ammo_tval = TVal.TV_BOLT;
                        state.ammo_mult = 3;
                        break;
                    }

                    /* Heavy Crossbow and Bolt */
                    case SVal.SV_HEAVY_XBOW:
                    {
                        state.ammo_tval = TVal.TV_BOLT;
                        state.ammo_mult = 4;
                        break;
                    }
                }

                /* Apply special flags */
                if (o_ptr.kind != null && !state.heavy_shoot)
                {
                    /* Extra shots */
                    state.num_shots += (short)extra_shots;

                    /* Extra might */
                    state.ammo_mult += (byte)extra_might;

                    /* Hack -- Rangers love Bows */
                    if (player_has(Misc.PF.EXTRA_SHOT.value) && (state.ammo_tval == TVal.TV_ARROW))
                    {
                        /* Extra shot at level 20 */
                        if (p_ptr.lev >= 20) state.num_shots++;

                        /* Extra shot at level 40 */
                        if (p_ptr.lev >= 40) state.num_shots++;
                    }
                }

                /* Require at least one shot */
                if (state.num_shots < 1) state.num_shots = 1;
            }

            /*** Analyze weapon ***/

            /* Examine the "current weapon" */
            o_ptr = inventory[Misc.INVEN_WIELD];

            /* Assume not heavy */
            state.heavy_wield = false;

            /* It is hard to hold a heavy weapon */
            if (hold < o_ptr.weight / 10)
            {
                /* Hard to wield a heavy weapon */
                state.to_h += (short)(2 * (hold - o_ptr.weight / 10));
                state.dis_to_h += (short)(2 * (hold - o_ptr.weight / 10));

                /* Heavy weapon */
                state.heavy_wield = true;
            }

            /* Non-object means barehanded attacks */
            if (o_ptr.kind == null)
                Misc.assert(o_ptr.weight == 0);

            /* Normal weapons */
            if (!state.heavy_wield)
            {
                /* Calculate number of blows */
                state.num_blows = (short)calc_blows(o_ptr, state, extra_blows);

                /* Boost digging skill by weapon weight */
                state.skills[(int)Skill.DIGGING] += (short)(o_ptr.weight / 10);
            }

            /* Assume okay */
            state.icky_wield = false;

            /* Priest weapon penalty for non-blessed edged weapons */
            if (player_has(Misc.PF.BLESS_WEAPON.value) && !p_ptr.check_state(Object_Flag.BLESSED, p_ptr.state.flags) &&
                ((o_ptr.tval == TVal.TV_SWORD) || (o_ptr.tval == TVal.TV_POLEARM)))
            {
                /* Reduce the real bonuses */
                state.to_h -= 2;
                state.to_d -= 2;

                /* Reduce the mental bonuses */
                state.dis_to_h -= 2;
                state.dis_to_d -= 2;

                /* Icky weapon */
                state.icky_wield = true;
            }

            return;
        }
示例#48
0
        public bool FA_would_be_obvious()
        {
            if (Misc.p_ptr.player_has(Misc.PF.CUMBER_GLOVE.value) && wield_slot() == Misc.INVEN_HANDS) {
                Bitflag flags = new Bitflag(Object_Flag.SIZE);
                object_flags(ref flags);

                if (!flags.has(Object_Flag.DEX.value) && !flags.has(Object_Flag.SPELLS_OK.value))
                    return true;
            }

            return false;
        }
示例#49
0
        /**
         * Determine whether a flagset includes any curse flags.
         */
        public static bool cursed_p(Bitflag f)
        {
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            f2.wipe();
            create_mask(f2, false, object_flag_type.CURSE);

            return f.is_inter(f2);
        }
示例#50
0
        /*
         * Have a monster choose a spell to cast.
         *
         * Note that the monster's spell list has already had "useless" spells
         * (bolts that won't hit the player, summons without room, etc.) removed.
         * Perhaps that should be done by this function.
         *
         * Stupid monsters will just pick a spell randomly.  Smart monsters
         * will choose more "intelligently".
         *
         * This function could be an efficiency bottleneck.
         */
        static int choose_attack_spell(int m_idx, Bitflag f)
        {
            throw new NotImplementedException();
            //monster_type *m_ptr = cave_monster(cave, m_idx);
            //monster_race *r_ptr = &r_info[m_ptr.r_idx];

            //int num = 0;
            //byte spells[RSF_MAX];

            //int i, py = p_ptr.py, px = p_ptr.px;

            //bool has_escape, has_attack, has_summon, has_tactic;
            //bool has_annoy, has_haste, has_heal;

            ///* Smart monsters restrict their spell choices. */
            //if (OPT(birth_ai_smart) && !rf_has(r_ptr.flags, RF_STUPID))
            //{
            //    /* What have we got? */
            //    has_escape = test_spells(f, RST_ESCAPE);
            //    has_attack = test_spells(f, RST_ATTACK | RST_BOLT | RST_BALL | RST_BREATH);
            //    has_summon = test_spells(f, RST_SUMMON);
            //    has_tactic = test_spells(f, RST_TACTIC);
            //    has_annoy = test_spells(f, RST_ANNOY);
            //    has_haste = test_spells(f, RST_HASTE);
            //    has_heal = test_spells(f, RST_HEAL);

            //    /*** Try to pick an appropriate spell type ***/

            //    /* Hurt badly or afraid, attempt to flee */
            //    if (has_escape && ((m_ptr.hp < m_ptr.maxhp / 4) || m_ptr.m_timed[MON_TMD_FEAR]))
            //    {
            //        /* Choose escape spell */
            //        set_spells(f, RST_ESCAPE);
            //    }

            //    /* Still hurt badly, couldn't flee, attempt to heal */
            //    else if (has_heal && m_ptr.hp < m_ptr.maxhp / 4)
            //    {
            //        /* Choose heal spell */
            //        set_spells(f, RST_HEAL);
            //    }

            //    /* Player is close and we have attack spells, blink away */
            //    else if (has_tactic && (distance(py, px, m_ptr.fy, m_ptr.fx) < 4) &&
            //             has_attack && (randint0(100) < 75))
            //    {
            //        /* Choose tactical spell */
            //        set_spells(f, RST_TACTIC);
            //    }

            //    /* We're hurt (not badly), try to heal */
            //    else if (has_heal && (m_ptr.hp < m_ptr.maxhp * 3 / 4) &&
            //             (randint0(100) < 60))
            //    {
            //        /* Choose heal spell */
            //        set_spells(f, RST_HEAL);
            //    }

            //    /* Summon if possible (sometimes) */
            //    else if (has_summon && (randint0(100) < 50))
            //    {
            //        /* Choose summon spell */
            //        set_spells(f, RST_SUMMON);
            //    }

            //    /* Attack spell (most of the time) */
            //    else if (has_attack && (randint0(100) < 85))
            //    {
            //        /* Choose attack spell */
            //        set_spells(f, RST_ATTACK | RST_BOLT | RST_BALL | RST_BREATH);
            //    }

            //    /* Try another tactical spell (sometimes) */
            //    else if (has_tactic && (randint0(100) < 50))
            //    {
            //        /* Choose tactic spell */
            //        set_spells(f, RST_TACTIC);
            //    }

            //    /* Haste self if we aren't already somewhat hasted (rarely) */
            //    else if (has_haste && (randint0(100) < (20 + r_ptr.speed - m_ptr.mspeed)))
            //    {
            //        /* Choose haste spell */
            //        set_spells(f, RST_HASTE);
            //    }

            //    /* Annoy player (most of the time) */
            //    else if (has_annoy && (randint0(100) < 85))
            //    {
            //        /* Choose annoyance spell */
            //        set_spells(f, RST_ANNOY);
            //    }

            //    /* Else choose no spell */
            //    else
            //    {
            //        rsf_wipe(f);
            //    }

            //    /* Anything left? */
            //    if (rsf_is_empty(f)) return (FLAG_END);
            //}

            ///* Extract all spells: "innate", "normal", "bizarre" */
            //for (i = FLAG_START, num = 0; i < RSF_MAX; i++)
            //{
            //    if (rsf_has(f, i)) spells[num++] = i;
            //}

            ///* Paranoia */
            //if (num == 0) return 0;

            ///* Pick at random */
            //return (spells[randint0(num)]);
        }
示例#51
0
        /*
         * Creatures can cast spells, shoot missiles, and breathe.
         *
         * Returns "true" if a spell (or whatever) was (successfully) cast.
         *
         * XXX XXX XXX This function could use some work, but remember to
         * keep it as optimized as possible, while retaining generic code.
         *
         * Verify the various "blind-ness" checks in the code.
         *
         * XXX XXX XXX Note that several effects should really not be "seen"
         * if the player is blind.
         *
         * Perhaps monsters should breathe at locations *near* the player,
         * since this would allow them to inflict "partial" damage.
         *
         * Perhaps smart monsters should decline to use "bolt" spells if
         * there is a monster in the way, unless they wish to kill it.
         *
         * It will not be possible to "correctly" handle the case in which a
         * monster attempts to attack a location which is thought to contain
         * the player, but which in fact is nowhere near the player, since this
         * might induce all sorts of messages about the attack itself, and about
         * the effects of the attack, which the player might or might not be in
         * a position to observe.  Thus, for simplicity, it is probably best to
         * only allow "faulty" attacks by a monster if one of the important grids
         * (probably the initial or final grid) is in fact in view of the player.
         * It may be necessary to actually prevent spell attacks except when the
         * monster actually has line of sight to the player.  Note that a monster
         * could be left in a bizarre situation after the player ducked behind a
         * pillar and then teleported away, for example.
         *
         * Note that this function attempts to optimize the use of spells for the
         * cases in which the monster has no spells, or has spells but cannot use
         * them, or has spells but they will have no "useful" effect.  Note that
         * this function has been an efficiency bottleneck in the past.
         *
         * Note the special "MFLAG_NICE" flag, which prevents a monster from using
         * any spell attacks until the player has had a single chance to move.
         */
        static bool make_attack_spell(int m_idx)
        {
            int chance, thrown_spell, rlev, failrate;

            Bitflag f = new Bitflag(Monster_Spell_Flag.SIZE);

            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx];

            //char m_name[80], m_poss[80], ddesc[80];
            string m_name, m_poss, ddesc;

            /* Player position */
            int px = Misc.p_ptr.px;
            int py = Misc.p_ptr.py;

            /* Extract the blind-ness */
            bool blind = (Misc.p_ptr.timed[(int)Timed_Effect.BLIND] != 0 ? true : false);

            /* Extract the "see-able-ness" */
            bool seen = (!blind && m_ptr.ml);

            /* Assume "normal" target */
            bool normal = true;

            /* Handle "leaving" */
            if (Misc.p_ptr.leaving) return false;

            /* Cannot cast spells when confused */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.CONF] != 0) return (false);

            /* Cannot cast spells when nice */
            if ((m_ptr.mflag & Monster_Flag.MFLAG_NICE) != 0) return false;

            /* Hack -- Extract the spell probability */
            chance = (r_ptr.freq_innate + r_ptr.freq_spell) / 2;

            /* Not allowed to cast spells */
            if (chance == 0) return false;

            /* Only do spells occasionally */
            if (Random.randint0(100) >= chance) return false;

            /* Hack -- require projectable player */
            if (normal)
            {
                /* Check range */
                if (m_ptr.cdis > Misc.MAX_RANGE) return false;

                /* Check path */
                if (!Cave.projectable(m_ptr.fy, m_ptr.fx, py, px, Spell.PROJECT_NONE))
                    return false;
            }

            /* Extract the monster level */
            rlev = ((r_ptr.level >= 1) ? r_ptr.level : 1);

            /* Extract the racial spell flags */
            f.copy(r_ptr.spell_flags);

            /* Allow "desperate" spells */
            if (r_ptr.flags.has(Monster_Flag.SMART.value) &&
                m_ptr.hp < m_ptr.maxhp / 10 &&
                Random.randint0(100) < 50){

                throw new NotImplementedException();

                ///* Require intelligent spells */
                //set_spells(f, RST_HASTE | RST_ANNOY | RST_ESCAPE | RST_HEAL | RST_TACTIC | RST_SUMMON);
            }

            /* Remove the "ineffective" spells */
            remove_bad_spells(m_idx, f);

            /* Check whether summons and bolts are worth it. */
            if (!r_ptr.flags.has(Monster_Flag.STUPID.value))
            {
                /* Check for a clean bolt shot */
                if (Monster_Spell_Flag.test_spells(f, Monster_Spell_Flag.mon_spell_type.RST_BOLT) &&
                    !clean_shot(m_ptr.fy, m_ptr.fx, py, px))

                    /* Remove spells that will only hurt friends */
                    Monster_Spell_Flag.set_spells(f, ~Monster_Spell_Flag.mon_spell_type.RST_BOLT);

                /* Check for a possible summon */
                if (!(summon_possible(m_ptr.fy, m_ptr.fx)))

                    /* Remove summoning spells */
                    Monster_Spell_Flag.set_spells(f, ~Monster_Spell_Flag.mon_spell_type.RST_SUMMON);
            }

            /* No spells left */
            if (f.is_empty()) return false;

            /* Get the monster name (or "it") */
            m_name = m_ptr.monster_desc(0x00);
            //Nick: Capatilize the first letter.
            m_name = Char.ToUpper(m_name[0]) + m_name.Substring(1);

            /* Get the monster possessive ("his"/"her"/"its") */
            m_poss = m_ptr.monster_desc(Desc.PRO2 | Desc.POSS);

            /* Get the "died from" name */
            ddesc = m_ptr.monster_desc(Desc.SHOW | Desc.IND2);

            /* Choose a spell to cast */
            thrown_spell = choose_attack_spell(m_idx, f);

            /* Abort if no spell was chosen */
            if (thrown_spell == 0) return false;

            /* If we see an unaware monster try to cast a spell, become aware of it */
            if (m_ptr.unaware)
                become_aware(m_idx);

            /* Calculate spell failure rate */
            failrate = 25 - (rlev + 3) / 4;
            if (m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] != 0)
                failrate += 20;

            /* Stupid monsters will never fail (for jellies and such) */
            if (Option.birth_ai_smart.value || r_ptr.flags.has(Monster_Flag.STUPID.value))
                failrate = 0;

            /* Check for spell failure (innate attacks never fail) */
            if ((thrown_spell >= Monster_Spell_Flag.MIN_NONINNATE_SPELL) && (Random.randint0(100) < failrate))
            {
                /* Message */
                Utilities.msg("{0} tries to cast a spell, but fails.", m_name);

                return true;
            }

            /* Cast the spell. */
            Cave.disturb(Misc.p_ptr, 1, 0);

            /* Special case RSF_HASTE until TMD_* and MON_TMD_* are rationalised */
            if (thrown_spell == Monster_Spell_Flag.HASTE.value) {
                if (blind)
                    Utilities.msg("{0} mumbles.", m_name);
                else
                    Utilities.msg("{0} concentrates on {1} body.", m_name, m_poss);

                mon_inc_timed(m_idx, Misc.MON_TMD.FAST, 50, 0, false);
            } else
                Monster_Spell_Flag.do_mon_spell(thrown_spell, m_idx, seen);

            /* Remember what the monster did to us */
            if (seen) {
                l_ptr.spell_flags.on(thrown_spell);

                /* Innate spell */
                if (thrown_spell < Monster_Spell_Flag.MIN_NONINNATE_SPELL) {
                    if (l_ptr.cast_innate < byte.MaxValue)
                        l_ptr.cast_innate++;
                } else {
                /* Bolt or Ball, or Special spell */
                    if (l_ptr.cast_spell < byte.MaxValue)
                        l_ptr.cast_spell++;
                }
            }
            /* Always take note of monsters that kill you */
            if (Misc.p_ptr.is_dead && (l_ptr.deaths < short.MaxValue)) {
                l_ptr.deaths++;
            }

            /* A spell was cast */
            return true;
        }
示例#52
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? */
        }
示例#53
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);
        }
示例#54
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();
            }
        }
示例#55
0
        /**
         * Notice a given special flag on wielded items.
         *
         * \param flag is the flag to notice
         */
        public static void wieldeds_notice_flag(Player.Player p, int flag)
        {
            int i;

            /* Sanity check */
            if (flag == 0) return;

            /* XXX Eddie need different naming conventions for starting wieldeds at INVEN_WIELD vs INVEN_WIELD+2 */
            for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++)
            {
                Object o_ptr = p.inventory[i];
                Bitflag f = new Bitflag(Object_Flag.SIZE);

                if (o_ptr.kind == null) continue;

                o_ptr.object_flags(ref f);

                if (f.has(flag) && !o_ptr.known_flags.has(flag))
                {
                    //char o_name[80];
                    string o_name = o_ptr.object_desc(Detail.BASE);

                    /* Notice the flag */
                    o_ptr.notice_flag(flag);

                    /* XXX Eddie should this go before noticing the flag to avoid learning twice? */
                    if (EASY_LEARN && o_ptr.is_jewelry())
                    {
                        /* XXX Eddie EASY_LEARN Possible concern: gets =teleportation just from +2 speed */
                        o_ptr.flavor_aware();
                        o_ptr.check_for_ident();
                    }

                    /* Message */
                    Object_Flag.flag_message(flag, o_name);
                }
                else
                {
                    /* Notice that flag is absent */
                    o_ptr.notice_flag(flag);
                }

                /* XXX Eddie should not need this, should be done in noticing, but will remove later */
                o_ptr.check_for_ident();

            }

            return;
        }
示例#56
0
        /**
         * Determine whether an object flag or its timed equivalent are set in the
         * passed-in flags (which probably come from a state structure). This assumes
         * that there are no p_ptr.timed effects which can be active yet unknown to
         * the player.
         *
         * \param p player to act upon
         * \param flag is the object flag for which we are checking.
         * \param f is the set of flags we're checking
         */
        public bool check_state(Object.Object_Flag flag, Bitflag f)
        {
            Object_Flag of_ptr = Object_Flag.list[flag.value];

            /* Sanity check */
            if (flag == null) return false;

            if (f.has(flag.value) || (of_ptr.timed != (Timed_Effect)0 && timed[(int)of_ptr.timed] > 0))
                return true;

            return false;
        }
示例#57
0
        static int obj_desc_inscrip(Object o_ptr, ref string buf, int max, int end)
        {
            string[] u = { "", "", "", "" };
            int      n = 0;

            Object.obj_pseudo_t feel        = o_ptr.pseudo();
            Bitflag             flags_known = new Bitflag(Object_Flag.SIZE);
            Bitflag             f2          = new Bitflag(Object_Flag.SIZE);

            o_ptr.object_flags_known(ref flags_known);

            /* Get inscription */
            if (o_ptr.note != null && o_ptr.note.value != null)
            {
                u[n++] = o_ptr.note.ToString();
            }

            /* Use special inscription, if any */
            if (!o_ptr.is_known() && feel != 0)
            {
                /* cannot tell excellent vs strange vs splendid until wield */
                if (!o_ptr.was_worn() && o_ptr.ego != null)
                {
                    u[n++] = "ego";
                }
                else
                {
                    u[n++] = Misc.inscrip_text[(int)feel];             //I know that feel bro.
                }
            }
            else if (((o_ptr.ident & Object.IDENT_EMPTY) != 0) && !o_ptr.is_known())
            {
                u[n++] = "empty";
            }
            else if (!o_ptr.is_known() && o_ptr.was_worn())
            {
                if (o_ptr.wield_slot() == Misc.INVEN_WIELD || o_ptr.wield_slot() == Misc.INVEN_BOW)
                {
                    u[n++] = "wielded";
                }
                else
                {
                    u[n++] = "worn";
                }
            }
            else if (!o_ptr.is_known() && o_ptr.was_fired())
            {
                u[n++] = "fired";
            }
            else if (!o_ptr.flavor_is_aware() && o_ptr.flavor_was_tried())
            {
                u[n++] = "tried";
            }

            /* Note curses */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.CURSE);
            if (flags_known.is_inter(f2))
            {
                u[n++] = "cursed";
            }

            /* Note squelch */
            if (Squelch.item_ok(o_ptr))
            {
                u[n++] = "squelch";
            }

            if (n != 0)
            {
                int i;
                for (i = 0; i < n; i++)
                {
                    if (i == 0)
                    {
                        buf = buf + " {";
                    }
                    buf = buf + u[i];
                    if (i < n - 1)
                    {
                        buf += ", ";
                    }
                }

                buf += "}";
            }

            return(end);
        }
示例#58
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);
        }
示例#59
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);
        }
示例#60
0
        /*
         * Obtain the flags for an item
         */
        public void object_flags(ref Bitflag flags)
        {
            flags.wipe();

            if (kind == null)
                return;

            flags.copy(this.flags);
        }