Beispiel #1
0
        /**
         * Get the slot multiplier for a flag's power rating
         *
         * \param flag is the flag in question.
         * \param slot is the wield_slot it's in.
         */
        public static int slot_mult(int flag, int slot)
        {
            Object_Flag of_ptr = list[flag];

            switch (slot)
            {
            case Misc.INVEN_WIELD:      return(of_ptr.weapon);

            case Misc.INVEN_BOW:        return(of_ptr.bow);

            case Misc.INVEN_LEFT:
            case Misc.INVEN_RIGHT:      return(of_ptr.ring);

            case Misc.INVEN_NECK:       return(of_ptr.amulet);

            case Misc.INVEN_LIGHT:      return(of_ptr.light);

            case Misc.INVEN_BODY:       return(of_ptr.body);

            case Misc.INVEN_OUTER:      return(of_ptr.cloak);

            case Misc.INVEN_ARM:        return(of_ptr.shield);

            case Misc.INVEN_HEAD:       return(of_ptr.hat);

            case Misc.INVEN_HANDS:      return(of_ptr.gloves);

            case Misc.INVEN_FEET:       return(of_ptr.boots);

            default:                    return(1);
            }
        }
Beispiel #2
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();
            }
        }
Beispiel #3
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);
        }
Beispiel #4
0
        /*
         * Attempt to make an object (normal or good/great)
         *
         * This routine plays nasty games to generate the "special artifacts".
         * We assume that the given object has been "wiped". You can optionally
         * receive the object's value in value if you pass a non-null pointer.
         *
         * Returns the whether or not creation worked.
         */
        public static bool make_object(Cave c, ref Object j_ptr, int lev, bool good, bool great, ref int value)
        {
            int         Base;
            Object_Kind kind;

            /* Try to make a special artifact */
            if (Random.one_in_(good ? 10 : 1000))
            {
                if (make_artifact_special(ref j_ptr, lev))
                {
                    if (value != 0)
                    {
                        value = j_ptr.value_real(1, false, true);
                    }
                    return(true);
                }

                /* If we failed to make an artifact, the player gets a great item */
                good = great = true;
            }

            /* Base level for the object */
            Base = (good ? (lev + 10) : lev);

            /* Get the object, prep it and apply magic */
            kind = get_obj_num(Base, good || great);
            if (kind == null)
            {
                return(false);
            }
            j_ptr.prep(kind, lev, aspect.RANDOMISE);
            j_ptr.apply_magic(lev, true, good, great);

            /* Generate multiple items */
            if (kind.gen_mult_prob >= Random.randint1(100))
            {
                j_ptr.number = (byte)Random.randcalc(kind.stack_size, lev, aspect.RANDOMISE);
            }

            if (value != 0)
            {
                value = j_ptr.value_real(j_ptr.number, false, true);
            }

            /* Return value, increased for uncursed out-of-depth objects */
            if (!Object_Flag.cursed_p(j_ptr.flags) && (kind.alloc_min > c.depth))
            {
                if (value != 0)
                {
                    value = (kind.alloc_min - c.depth) * (value / 5);
                }
            }

            return(true);
        }
Beispiel #5
0
        /**
         * Print a message when an object flag is identified by use.
         *
         * \param flag is the flag being noticed
         * \param name is the object name
         */
        public static void flag_message(int flag, string name)
        {
            Object_Flag of_ptr = Object_Flag.list[flag];

            if (of_ptr.message != null && of_ptr.message != "")
            {
                Utilities.msg(of_ptr.message, name);
            }

            return;
        }
Beispiel #6
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;
        }
Beispiel #7
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;
        }
Beispiel #8
0
        Monster_Flag resist_flag; /* Which monster flag(s) make it resist */

        #endregion Fields

        #region Constructors

        public Slay(string name, Object_Flag object_flag, Monster_Flag monster_flag, Monster_Flag resist_flag,
            int mult, string range_verb, string melee_verb, string active_verb, string desc, string brand)
        {
            this.value = counter++;

            this.name = name;
            this.object_flag = object_flag;
            this.monster_flag = monster_flag;
            this.resist_flag = resist_flag;
            this.mult = mult;
            this.range_verb = range_verb;
            this.melee_verb = melee_verb;
            this.active_verb = active_verb;
            this.desc = desc;
            this.brand = brand;

            list.Add(this);
        }
Beispiel #9
0
        public Slay(string name, Object_Flag object_flag, Monster_Flag monster_flag, Monster_Flag resist_flag,
                    int mult, string range_verb, string melee_verb, string active_verb, string desc, string brand)
        {
            this.value = counter++;

            this.name         = name;
            this.object_flag  = object_flag;
            this.monster_flag = monster_flag;
            this.resist_flag  = resist_flag;
            this.mult         = mult;
            this.range_verb   = range_verb;
            this.melee_verb   = melee_verb;
            this.active_verb  = active_verb;
            this.desc         = desc;
            this.brand        = brand;

            list.Add(this);
        }
Beispiel #10
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());
        }
Beispiel #11
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);
        }
Beispiel #12
0
        public GF(string name, string desc, Object_Flag resist, int num, random_value denom, Timed_Effect opp,
            Object_Flag immunity, bool side_immune, Object_Flag vuln, Monster_Flag mon_res, Monster_Flag mon_vuln,
            Object_Flag obj_hates, Object_Flag obj_imm)
        {
            value = counter++;
            this.name = name;
            this.desc = desc;
            this.resist = resist;
            this.num = num;
            this.denom = denom;
            this.opp = opp;
            this.immunity = immunity;
            this.side_immune = side_immune;
            this.vuln = vuln;
            this.mon_res = mon_res;
            this.mon_vuln = mon_vuln;
            this.obj_hates = obj_hates;
            this.obj_imm = obj_imm;

            list.Add(this);
        }
Beispiel #13
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);
        }
Beispiel #14
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);
        }
Beispiel #15
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);
        }
        /*
         * Learn about an "observed" resistance or other player state property, or
         * lack of it.
         */
        public void update_smart_learn(Player.Player p, Object_Flag what)
        {
            Monster_Race r_ptr = Misc.r_info[r_idx];

            /* Sanity check */
            if (what != null) return;

            /* anything a monster might learn, the player should learn */
            Object.Object.wieldeds_notice_flag(p, what.value);

            /* Not allowed to learn */
            if (!Option.birth_ai_learn.value) return;

            /* Too stupid to learn anything */
            if (r_ptr.flags.has(Monster_Flag.STUPID.value)) return;

            /* Not intelligent, only learn sometimes */
            if (!r_ptr.flags.has(Monster_Flag.SMART.value) && Random.one_in_(2)) return;

            /* Analyze the knowledge; fail very rarely */
            if (p.check_state(what, p.state.flags) && !Random.one_in_(100))
                known_pflags.on(what.value);
            else
                known_pflags.off(what.value);
        }
Beispiel #17
0
        /*
         * Special display, part 2c
         *
         * How to print out the modifications and sustains.
         * Positive mods with no sustain will be light green.
         * Positive mods with a sustain will be dark green.
         * Sustains (with no modification) will be a dark green 's'.
         * Negative mods (from a curse) will be red.
         * Huge mods (>9), like from MICoMorgoth, will be a '*'
         * No mod, no sustain, will be a slate '.'
         */
        static void display_player_sust_info()
        {
            int j, stat;

            Player.Player p_ptr = Player.Player.instance;

            Bitflag f = new Bitflag(Object_Flag.SIZE);

            Object_Flag[] stat_flags = new Object_Flag[(int)Stat.Max];
            Object_Flag[] sustain_flags = new Object_Flag[(int)Stat.Max];

            ConsoleColor a;
            char c;

            /* Row */
            int row = 2;

            /* Column */
            int col = 26;

            /* Build the stat flags tables */
            stat_flags[(int)Stat.Str] = Object_Flag.STR;
            stat_flags[(int)Stat.Int] = Object_Flag.INT;
            stat_flags[(int)Stat.Wis] = Object_Flag.WIS;
            stat_flags[(int)Stat.Dex] = Object_Flag.DEX;
            stat_flags[(int)Stat.Con] = Object_Flag.CON;
            stat_flags[(int)Stat.Chr] = Object_Flag.CHR;
            sustain_flags[(int)Stat.Str] = Object_Flag.SUST_STR;
            sustain_flags[(int)Stat.Int] = Object_Flag.SUST_INT;
            sustain_flags[(int)Stat.Wis] = Object_Flag.SUST_WIS;
            sustain_flags[(int)Stat.Dex] = Object_Flag.SUST_DEX;
            sustain_flags[(int)Stat.Con] = Object_Flag.SUST_CON;
            sustain_flags[(int)Stat.Chr] = Object_Flag.SUST_CHR;

            /* Header */
            Utilities.c_put_str(ConsoleColor.White, "abcdefghijkl@", row-1, col);

            /* Process equipment */
            for (int i = Misc.INVEN_WIELD; i < Misc.INVEN_TOTAL; ++i)
            {
                /* Get the object */
                Object.Object o_ptr = p_ptr.inventory[i];

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

                /* Get the "known" flags */
                o_ptr.object_flags_known(ref f);

                /* Initialize color based of sign of pval. */
                for (stat = 0; stat < (int)Stat.Max; stat++)
                {
                    /* Default */
                    a = ConsoleColor.Gray;
                    c = '.';

                    /* Boost */
                    if (f.has(stat_flags[stat].value))
                    {
                        /* Default */
                        c = '*';

                        /* Work out which pval we're talking about */
                        j = o_ptr.which_pval(stat_flags[stat].value);

                        /* Good */
                        if (o_ptr.pval[j] > 0)
                        {
                            /* Good */
                            a = ConsoleColor.Green;

                            /* Label boost */
                            if (o_ptr.pval[j] < 10)
                                c = (char)Basic.I2D((char)o_ptr.pval[j]);
                        }

                        /* Bad */
                        if (o_ptr.pval[j] < 0)
                        {
                            /* Bad */
                            a = ConsoleColor.Red;

                            /* Label boost */
                            if (o_ptr.pval[j] > -10)
                                c = (char)Basic.I2D((char)-(o_ptr.pval[j]));
                        }
                    }

                    /* Sustain */
                    if (f.has(sustain_flags[stat].value))
                    {
                        /* Dark green */
                        a = ConsoleColor.DarkGreen;

                        /* Convert '.' to 's' */
                        if (c == '.') c = 's';
                    }

                    if ((c == '.') && o_ptr.kind != null && !o_ptr.object_flag_is_known(sustain_flags[stat].value))
                        c = '?';

                    /* Dump proper character */
                    Term.putch(col, row+stat, a, c);
                }

                /* Advance */
                col++;
            }

            /* Player flags */
            Player.Player.player_flags(ref f);

            /* Check stats */
            for (stat = 0; stat < (int)Stat.Max; ++stat)
            {
                /* Default */
                a = ConsoleColor.Gray;
                c = '.';

                /* Sustain */
                if (f.has(sustain_flags[stat].value))
                {
                    /* Dark green "s" */
                    a = ConsoleColor.DarkGreen;
                    c = 's';
                }

                /* Dump */
                Term.putch(col, row+stat, a, c);
            }

            /* Column */
            col = 26;

            /* Footer */
            Utilities.c_put_str(ConsoleColor.White, "abcdefghijkl@", row+6, col);

            /* Equippy */
            display_player_equippy(row+7, col);
        }
Beispiel #18
0
        /**
         * Ascertain whether a flag is granular (pval-based) or binary.
         */
        public static bool flag_uses_pval(int flag)
        {
            Object_Flag of_ptr = list[flag];

            return(of_ptr.pval);
        }
Beispiel #19
0
        /**
         * Select an ego-item that fits the object's tval and sval.
         */
        Ego_Item ego_find_random(int level)
        {
            int  i, j;
            long total = 0L;

            /* XXX alloc_ego_table &c should be static to this file */
            CSAngband.Init.alloc_entry[] table = CSAngband.Init.alloc_ego_table;
            Ego_Item ego;

            /* Go through all possible ego items and find oens which fit this item */
            for (i = 0; i < CSAngband.Init.alloc_ego_size; i++)
            {
                /* Reset any previous probability of this type being picked */
                table[i].prob3 = 0;

                if (level < table[i].level)
                {
                    continue;
                }

                /* Access the ego item */
                ego = Misc.e_info[table[i].index];

                /* XXX Ignore cursed items for now */
                if (Object_Flag.cursed_p(ego.flags))
                {
                    continue;
                }

                /* Test if this is a legal ego-item type for this object */
                for (j = 0; j < Misc.EGO_TVALS_MAX; j++)
                {
                    /* Require identical base type */
                    if (tval == ego.tval[j] &&
                        sval >= ego.min_sval[j] &&
                        sval <= ego.max_sval[j])
                    {
                        table[i].prob3 = table[i].prob2;
                        break;
                    }
                }

                /* Total */
                total += table[i].prob3;
            }

            if (total != 0)
            {
                long value = Random.randint0((int)total);
                for (i = 0; i < CSAngband.Init.alloc_ego_size; i++)
                {
                    /* Found the entry */
                    if (value < table[i].prob3)
                    {
                        break;
                    }

                    /* Decrement */
                    value = value - table[i].prob3;
                }

                return(Misc.e_info[table[i].index]);
            }

            return(null);
        }
Beispiel #20
0
 public set(Object_Flag.object_flag_type a, int b, int c, int d, bool e, int f, string g)
 {
     type = (int)a;
     factor = b;
     bonus = c;
     size = d;
     dam_dep = e;
     count = f;
     desc = g;
 }
Beispiel #21
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);
        }
Beispiel #22
0
        /**
         * Return the OFT_ type of a flag.
         */
        public static int obj_flag_type(int flag)
        {
            Object_Flag of_ptr = list[flag];

            return((int)of_ptr.type);
        }
Beispiel #23
0
        /**
         * Return the pval weighting of a flag. (Some pvals are more important than
         * others.)
         */
        public static int pval_mult(int flag)
        {
            Object_Flag of_ptr = list[flag];

            return(of_ptr.p_m);           //pval_mult; <--Nick: Assuming p_m = pval_mult...
        }
        public bool timed; /* true if timed, false if permanent */

        #endregion Fields

        #region Constructors

        public Monster_Spell_Effect_Flag(int index, Monster_Spell_Flag method, GF gf, bool timed, Timed_Effect flag,
            random_value Base, random_value dam, int chance, bool save, Object_Flag res_flag, random_value power)
        {
            this.index = index;
            this.method = method;
            this.gf = gf;
            this.timed = timed;
            this.flag = flag;
            this.Base = Base;
            this.dam = dam;
            this.chance = chance;
            this.save = save;
            this.res_flag = res_flag;
            this.power = power;
        }
Beispiel #25
0
        /**
         * Return the base power rating for a flag.
         */
        public static int flag_power(int flag)
        {
            Object_Flag of_ptr = list[flag];

            return(of_ptr.power);
        }
Beispiel #26
0
            public Object_Flag vuln_flag; /* corresponding vulnerability flag, if any */

            #endregion Fields

            #region Constructors

            public player_flag_record(string n, Object_Flag r, Object_Flag i, Object_Flag v)
            {
                name = n;
                res_flag = r;
                im_flag = i;
                vuln_flag = v;
            }
Beispiel #27
0
 public timed_effect(string a, string b, string c, string d, uint e, uint f, Message_Type g, Object_Flag h)
 {
     on_begin = a;
     on_end = b;
     on_increase = c;
     on_decrease = d;
     flag_redraw = e;
     flag_update = f;
     msg = g;
     resist = h;
 }
Beispiel #28
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? */
        }