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

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

            return(count);
        }
Пример #2
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);
        }
Пример #3
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 */
            }
        }
Пример #4
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);
        }
Пример #5
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;
        }