Esempio n. 1
0
        /**
         * Notice things about an object that would be noticed in time.
         */
        static void object_notice_after_time()
        {
            int i;
            int flag;

            Object o_ptr;
            string o_name;            //[80];

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

            Object_Flag.create_mask(timed_mask, true, Object_Flag.object_flag_id.TIMED);

            /* Check every item the player is wearing */
            for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++)
            {
                o_ptr = Misc.p_ptr.inventory[i];

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

                /* Check for timed notice flags */
                o_name = o_ptr.object_desc(Detail.BASE);
                o_ptr.object_flags(ref f);
                f.inter(timed_mask);

                for (flag = f.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = f.next(flag + 1))
                {
                    if (!o_ptr.known_flags.has(flag))
                    {
                        /* Message */
                        Object_Flag.flag_message(flag, o_name);

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

                        if (o_ptr.is_jewelry() && (o_ptr.effect() == null || o_ptr.effect_is_known()))
                        {
                            /* XXX this is a small hack, but jewelry with anything noticeable really is obvious */
                            /* XXX except, wait until learn activation if that is only clue */
                            o_ptr.flavor_aware();
                            o_ptr.check_for_ident();
                        }
                    }
                    else
                    {
                        /* Notice the flag is absent */
                        o_ptr.notice_flag(flag);
                    }
                }

                /* XXX Is this necessary? */
                o_ptr.check_for_ident();
            }
        }
Esempio n. 2
0
        /**
         * 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);
        }
Esempio n. 3
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());
        }
Esempio n. 4
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();
        }
Esempio n. 5
0
        /**
         * Notice things about an object that would be noticed in time.
         */
        static void object_notice_after_time()
        {
            int i;
            int flag;

            Object o_ptr;
            string o_name;//[80];

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

            Object_Flag.create_mask(timed_mask, true, Object_Flag.object_flag_id.TIMED);

            /* Check every item the player is wearing */
            for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++)
            {
                o_ptr = Misc.p_ptr.inventory[i];

                if (o_ptr.kind == null || o_ptr.is_known()) continue;

                /* Check for timed notice flags */
                o_name = o_ptr.object_desc(Detail.BASE);
                o_ptr.object_flags(ref f);
                f.inter(timed_mask);

                for (flag = f.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = f.next(flag + 1))
                {
                    if (!o_ptr.known_flags.has(flag))
                    {
                        /* Message */
                        Object_Flag.flag_message(flag, o_name);

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

                        if (o_ptr.is_jewelry() && (o_ptr.effect() == null || o_ptr.effect_is_known()))
                        {
                            /* XXX this is a small hack, but jewelry with anything noticeable really is obvious */
                            /* XXX except, wait until learn activation if that is only clue */
                            o_ptr.flavor_aware();
                            o_ptr.check_for_ident();
                        }
                    }
                    else
                    {
                        /* Notice the flag is absent */
                        o_ptr.notice_flag(flag);
                    }
                }

                /* XXX Is this necessary? */
                o_ptr.check_for_ident();
            }
        }
Esempio n. 6
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 */
            }
        }
Esempio n. 7
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;
        }
Esempio n. 8
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);
        }
Esempio n. 9
0
        /**
         * Calculate the rating for a given slay combination
         */
        int slay_power(bool verbose, StreamWriter log_file, bool known)
        {
            Bitflag      s_index = new Bitflag(Object_Flag.SIZE);
            Bitflag      f = new Bitflag(Object_Flag.SIZE);
            Bitflag      f2 = new Bitflag(Object_Flag.SIZE);
            int          sv = 0;    //uint
            int          i, j;
            int          mult;
            Slay         best_s_ptr = null;
            Monster_Race r_ptr;

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

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

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

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

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

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

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

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

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

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

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

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

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

            return(sv);
        }
Esempio n. 10
0
        /**
         * Create a cache of slay combinations found on ego items, and the values of
         * these combinations. This is to speed up slay_power(), which will be called
         * many times for ego items during the game.
         *
         * \param items is the set of ego types from which we are extracting slay
         * combinations
         */
        public static int create_slay_cache(Ego_Item[] items)
        {
            int     count     = 0;
            Bitflag cacheme   = new Bitflag(Object_Flag.SIZE);
            Bitflag slay_mask = new Bitflag(Object_Flag.SIZE);

            /* Build the slay mask */
            Object_Flag.create_mask(slay_mask, false, Object_Flag.object_flag_type.SLAY,
                                    Object_Flag.object_flag_type.KILL, Object_Flag.object_flag_type.BRAND);

            /* Calculate necessary size of slay_cache */
            Bitflag[] dupcheck = new Bitflag[Misc.z_info.e_max];

            for (int i = 0; i < Misc.z_info.e_max; i++)
            {
                dupcheck[i] = new Bitflag(Object_Flag.SIZE);
                Ego_Item e_ptr = items[i];

                //Some items are null... I guess we should just skip them...?
                //TODO: Find out why they are null, and see if we actually should just skip them...
                if (e_ptr == null)
                {
                    continue;
                }

                /* Find the slay flags on this ego */
                cacheme.copy(e_ptr.flags);
                cacheme.inter(slay_mask);

                /* Only consider non-empty combinations of slay flags */
                if (!cacheme.is_empty())
                {
                    /* Skip previously scanned combinations */
                    for (int j = 0; j < i; j++)
                    {
                        if (cacheme.is_equal(dupcheck[j]))
                        {
                            continue;
                        }
                    }

                    /* msg("Found a new slay combo on an ego item"); */
                    count++;
                    dupcheck[i].copy(cacheme);
                }
            }

            /* Allocate slay_cache with an extra empty element for an iteration stop */
            slay_cache = new flag_cache[count + 1];
            count      = 0;

            /* Populate the slay_cache */
            for (int i = 0; i < Misc.z_info.e_max; i++)
            {
                if (!dupcheck[i].is_empty())
                {
                    slay_cache[count] = new flag_cache();
                    slay_cache[count].flags.copy(dupcheck[i]);
                    slay_cache[count].value = 0;
                    count++;
                    /*msg("Cached a slay combination");*/
                }
            }

            //From a time without garbage collection...

            /*for (i = 0; i < z_info.e_max; i++)
             *  FREE(dupcheck[i]);
             * FREE(dupcheck);*/

            /* Success */
            return(0);
        }
Esempio n. 11
0
        /**
         * Calculate the rating for a given slay combination
         */
        int slay_power(bool verbose, StreamWriter log_file, bool known)
        {
            Bitflag s_index = new Bitflag(Object_Flag.SIZE);
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);
            int sv = 0; //uint
            int i, j;
            int mult;
            Slay best_s_ptr = null;
            Monster_Race r_ptr;
            Monster.Monster m_ptr;
            //monster_type monster_type_body;
            string[] desc = new string[Slay.MAX.value];// = { 0 }, *
            string[] brand = new string[Slay.MAX.value];// = { 0 };
            int[] s_mult = new int[Slay.MAX.value];// = { 0 };

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

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

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

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

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

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

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

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

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

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

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

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

            return sv;
        }
Esempio n. 12
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;
        }
Esempio n. 13
0
        /**
         * Create a cache of slay combinations found on ego items, and the values of
         * these combinations. This is to speed up slay_power(), which will be called
         * many times for ego items during the game.
         *
         * \param items is the set of ego types from which we are extracting slay
         * combinations
         */
        public static int create_slay_cache(Ego_Item[] items)
        {
            int count = 0;
            Bitflag cacheme = new Bitflag(Object_Flag.SIZE);
            Bitflag slay_mask = new Bitflag(Object_Flag.SIZE);

            /* Build the slay mask */
            Object_Flag.create_mask(slay_mask, false, Object_Flag.object_flag_type.SLAY,
                Object_Flag.object_flag_type.KILL, Object_Flag.object_flag_type.BRAND);

            /* Calculate necessary size of slay_cache */
            Bitflag[] dupcheck = new Bitflag[Misc.z_info.e_max];

            for (int i = 0; i < Misc.z_info.e_max; i++) {
                dupcheck[i] = new Bitflag(Object_Flag.SIZE);
                Ego_Item e_ptr = items[i];

                //Some items are null... I guess we should just skip them...?
                //TODO: Find out why they are null, and see if we actually should just skip them...
                if(e_ptr == null) {
                    continue;
                }

                /* Find the slay flags on this ego */
                cacheme.copy(e_ptr.flags);
                cacheme.inter(slay_mask);

                /* Only consider non-empty combinations of slay flags */
                if (!cacheme.is_empty()) {
                    /* Skip previously scanned combinations */
                    for (int j = 0; j < i; j++)
                        if (cacheme.is_equal(dupcheck[j])) continue;

                    /* msg("Found a new slay combo on an ego item"); */
                    count++;
                    dupcheck[i].copy(cacheme);
                }
            }

            /* Allocate slay_cache with an extra empty element for an iteration stop */
            slay_cache = new flag_cache[count + 1];
            count = 0;

            /* Populate the slay_cache */
            for (int i = 0; i < Misc.z_info.e_max; i++) {
                if (!dupcheck[i].is_empty()) {
                    slay_cache[count] = new flag_cache();
                    slay_cache[count].flags.copy(dupcheck[i]);
                    slay_cache[count].value = 0;
                    count++;
                    /*msg("Cached a slay combination");*/
                }
            }

            //From a time without garbage collection...
            /*for (i = 0; i < z_info.e_max; i++)
                FREE(dupcheck[i]);
            FREE(dupcheck);*/

            /* Success */
            return 0;
        }