Exemple #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);
        }
Exemple #2
0
        /**
         * Extract the multiplier from a given object hitting a given monster.
         *
         * \param o_ptr is the object being used to attack
         * \param m_ptr is the monster being attacked
         * \param best_s_ptr is the best applicable slay_table entry, or null if no
         *  slay already known
         * \param real is whether this is a real attack (where we update lore) or a
         *  simulation (where we don't)
         * \param known_only is whether we are using all the object flags, or only
         * the ones we *already* know about
         */
        //Best_s_ptr was slay**
        public static void improve_attack_modifier(Object o_ptr, Monster.Monster m_ptr,
                                                   ref Slay best_s_ptr, bool real, bool known_only)
        {
            Monster_Race r_ptr   = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr   = Misc.l_list[m_ptr.r_idx];
            Bitflag      f       = new Bitflag(Object_Flag.SIZE);
            Bitflag      known_f = new Bitflag(Object_Flag.SIZE);
            Bitflag      note_f  = new Bitflag(Object_Flag.SIZE);
            int          i;

            o_ptr.object_flags(ref f);
            o_ptr.object_flags_known(ref known_f);

            for (i = 0; i < Slay.MAX.value; i++)
            {
                Slay s_ptr = list[i];
                if ((known_only && !known_f.has(s_ptr.object_flag.value)) || (!known_only && !f.has(s_ptr.object_flag.value)))
                {
                    continue;
                }

                /* In a real attack, learn about monster resistance or slay match if:
                 * EITHER the slay flag on the object is known,
                 * OR the monster is vulnerable to the slay/brand
                 */
                if (real && (known_f.has(s_ptr.object_flag.value) || (s_ptr.monster_flag != Monster_Flag.NONE &&
                                                                      r_ptr.flags.has(s_ptr.monster_flag.value)) ||
                             (s_ptr.resist_flag != Monster_Flag.NONE && !r_ptr.flags.has(s_ptr.resist_flag.value))))
                {
                    /* notice any brand or slay that would affect monster */
                    note_f.wipe();
                    note_f.on(s_ptr.object_flag.value);
                    object_notice_slays(o_ptr, note_f);

                    if (m_ptr.ml && s_ptr.monster_flag != Monster_Flag.NONE)
                    {
                        l_ptr.flags.on(s_ptr.monster_flag.value);
                    }

                    if (m_ptr.ml && s_ptr.resist_flag != Monster_Flag.NONE)
                    {
                        l_ptr.flags.on(s_ptr.resist_flag.value);
                    }
                }

                /* If the monster doesn't resist or the slay flag matches */
                if ((s_ptr.brand != null && s_ptr.brand.Length != 0 &&
                     !r_ptr.flags.has(s_ptr.resist_flag.value)) ||
                    (s_ptr.monster_flag != Monster_Flag.NONE &&
                     r_ptr.flags.has(s_ptr.monster_flag.value)))
                {
                    /* compare multipliers to determine best attack */
                    if ((best_s_ptr == null) || ((best_s_ptr).mult < s_ptr.mult))
                    {
                        best_s_ptr = s_ptr;
                    }
                }
            }
        }
Exemple #3
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;
        }
Exemple #4
0
        static int obj_desc_light(Object o_ptr, ref string buf, int max, int end)
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);

            o_ptr.object_flags(ref f);

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

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

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

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

            return(false);
        }
Exemple #6
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);
        }
Exemple #7
0
        /**
         * This is a safe way to choose a random new flag to add to an object.
         * It takes the existing flags and an array of new flags,
         * and returns an entry from newf, or 0 if there are no
         * new flags available.
         */
        static int get_new_attr(Bitflag flags, Bitflag newf)
        {
            int options = 0, flag = 0;

            for (int i = newf.next(Bitflag.FLAG_START); i != Bitflag.FLAG_null; i = newf.next(i + 1))
            {
                /* skip this one if the flag is already present */
                if (flags.has(i))
                {
                    continue;
                }

                /* each time we find a new possible option, we have a 1-in-N chance of
                 * choosing it and an (N-1)-in-N chance of keeping a previous one */
                if (Random.one_in_(++options))
                {
                    flag = i;
                }
            }

            return(flag);
        }
Exemple #8
0
        /*
         * Calculate the players current "state", taking into account
         * not only race/class intrinsics, but also objects being worn
         * and temporary spell effects.
         *
         * See also calc_mana() and calc_hitpoints().
         *
         * Take note of the new "speed code", in particular, a very strong
         * player will start slowing down as soon as he reaches 150 pounds,
         * but not until he reaches 450 pounds will he be half as fast as
         * a normal kobold.  This both hurts and helps the player, hurts
         * because in the old days a player could just avoid 300 pounds,
         * and helps because now carrying 300 pounds is not very painful.
         *
         * The "weapon" and "bow" do *not* add to the bonuses to hit or to
         * damage, since that would affect non-combat things.  These values
         * are actually added in later, at the appropriate place.
         *
         * If id_only is true, calc_bonuses() will only use the known
         * information of objects; thus it returns what the player _knows_
         * the character state to be.
         */
        void calc_bonuses(Object.Object[] inventory, ref Player_State state, bool id_only)
        {
            Player p_ptr = Player.instance;
            int i, j, hold;

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

            Object.Object o_ptr;

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

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

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

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

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

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

            /*** Analyze player ***/

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

            /*** Analyze equipment ***/

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

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

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

                collect_f.union(f);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            /*** Update all flags ***/

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

            /*** Handle stats ***/

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

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

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

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

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

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

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

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

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

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

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

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

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

            /*** Temporary flags ***/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            /*** Analyze weight ***/

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

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

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

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

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

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

            /*** Apply modifier bonuses ***/

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

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

            /*** Modify skills ***/

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

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

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

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

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

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

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

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

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

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

            /*** Analyze current bow ***/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            /*** Analyze weapon ***/

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

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

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

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

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

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

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

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

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

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

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

            return;
        }
Exemple #9
0
        /*
         * Calculate maximum mana.  You do not need to know any spells.
         * Note that mana is lowered by heavy (or inappropriate) armor.
         *
         * This function induces status messages.
         */
        static void calc_mana()
        {
            int msp, levels, cur_wgt, max_wgt;

            Object.Object o_ptr;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            /* Take note when "armor state" changes */
            if (old_cumber_armor != instance.cumber_armor)
            {
                /* Message */
                if (instance.cumber_armor)
                {
                    Utilities.msg("The weight of your armor encumbers your movement.");
                }
                else
                {
                    Utilities.msg("You feel able to move more freely.");
                }
            }
        }
Exemple #10
0
        /*
         * Calculate and set the current light radius.
         *
         * The brightest wielded object counts as the light source; radii do not add
         * up anymore.
         *
         * Note that a cursed light source no longer emits light.
         */
        void calc_torch()
        {
            int i;

            short old_light = cur_light;
            bool burn_light = true;

            short new_light = 0;
            int extra_light = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            /* Notice changes in the "light radius" */
            if (old_light != new_light)
            {
                /* Update the visuals */
                cur_light = new_light;
                update |= (Misc.PU_UPDATE_VIEW | Misc.PU_MONSTERS);
            }
        }
Exemple #11
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? */
        }
Exemple #12
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;
        }
Exemple #13
0
        public bool FA_would_be_obvious()
        {
            if (Misc.p_ptr.player_has(Misc.PF.CUMBER_GLOVE.value) && wield_slot() == Misc.INVEN_HANDS) {
                Bitflag flags = new Bitflag(Object_Flag.SIZE);
                object_flags(ref flags);

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

            return false;
        }
Exemple #14
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);
        }
Exemple #15
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;
        }
Exemple #16
0
        static int obj_desc_combat(Object o_ptr, ref string buf, int max, int end, bool spoil)
        {
            Bitflag flags       = new Bitflag(Object_Flag.SIZE);
            Bitflag flags_known = new Bitflag(Object_Flag.SIZE);

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

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

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

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

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


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

            return(end);
        }
Exemple #17
0
        /**
         * Extract the multiplier from a given object hitting a given monster.
         *
         * \param o_ptr is the object being used to attack
         * \param m_ptr is the monster being attacked
         * \param best_s_ptr is the best applicable slay_table entry, or null if no
         *  slay already known
         * \param real is whether this is a real attack (where we update lore) or a
         *  simulation (where we don't)
         * \param known_only is whether we are using all the object flags, or only
         * the ones we *already* know about
         */
        //Best_s_ptr was slay**
        public static void improve_attack_modifier(Object o_ptr, Monster.Monster m_ptr, 
			ref Slay best_s_ptr, bool real, bool known_only)
        {
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx];
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag known_f = new Bitflag(Object_Flag.SIZE);
            Bitflag note_f = new Bitflag(Object_Flag.SIZE);
            int i;

            o_ptr.object_flags(ref f);
            o_ptr.object_flags_known(ref known_f);

            for (i = 0; i < Slay.MAX.value; i++) {
                Slay s_ptr = list[i];
                if ((known_only && !known_f.has(s_ptr.object_flag.value)) || (!known_only && !f.has(s_ptr.object_flag.value)))
                    continue;

                /* In a real attack, learn about monster resistance or slay match if:
                 * EITHER the slay flag on the object is known,
                 * OR the monster is vulnerable to the slay/brand
                 */
                if (real && (known_f.has(s_ptr.object_flag.value) || (s_ptr.monster_flag != Monster_Flag.NONE
                        && r_ptr.flags.has(s_ptr.monster_flag.value)) ||
                        (s_ptr.resist_flag != Monster_Flag.NONE && !r_ptr.flags.has(s_ptr.resist_flag.value)))) {

                    /* notice any brand or slay that would affect monster */
                    note_f.wipe();
                    note_f.on(s_ptr.object_flag.value);
                    object_notice_slays(o_ptr, note_f);

                    if (m_ptr.ml && s_ptr.monster_flag != Monster_Flag.NONE)
                        l_ptr.flags.on(s_ptr.monster_flag.value);

                    if (m_ptr.ml && s_ptr.resist_flag != Monster_Flag.NONE)
                        l_ptr.flags.on(s_ptr.resist_flag.value);
                }

                /* If the monster doesn't resist or the slay flag matches */
                if ((s_ptr.brand != null && s_ptr.brand.Length != 0 &&
                        !r_ptr.flags.has(s_ptr.resist_flag.value)) ||
                        (s_ptr.monster_flag != Monster_Flag.NONE &&
                        r_ptr.flags.has(s_ptr.monster_flag.value))) {

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

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

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

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

            o_ptr.object_flags(ref f);

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

            return buf.Length;
        }
Exemple #20
0
        static int obj_desc_combat(Object o_ptr, ref string buf, int max, int end, bool spoil)
        {
            Bitflag flags = new Bitflag(Object_Flag.SIZE);
            Bitflag flags_known = new Bitflag(Object_Flag.SIZE);

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

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

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

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

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

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

            return end;
        }
Exemple #21
0
        /**
         * This is a safe way to choose a random new flag to add to an object.
         * It takes the existing flags and an array of new flags,
         * and returns an entry from newf, or 0 if there are no
         * new flags available.
         */
        static int get_new_attr(Bitflag flags, Bitflag newf)
        {
            int options = 0, flag = 0;

            for (int i = newf.next(Bitflag.FLAG_START); i != Bitflag.FLAG_null; i = newf.next(i + 1))
            {
                /* skip this one if the flag is already present */
                if (flags.has(i)) continue;

                /* each time we find a new possible option, we have a 1-in-N chance of
                 * choosing it and an (N-1)-in-N chance of keeping a previous one */
                if (Random.one_in_(++options)) flag = i;
            }

            return flag;
        }
Exemple #22
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? */
        }
Exemple #23
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;
        }
Exemple #24
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;
        }