Beispiel #1
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;
                    }
                }
            }
        }
Beispiel #2
0
        /**
         * Notice a given special flag on wielded items.
         *
         * \param flag is the flag to notice
         */
        public static void wieldeds_notice_flag(Player.Player p, int flag)
        {
            int i;

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

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

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

                o_ptr.object_flags(ref f);

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

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

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

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

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

            return;
        }
Beispiel #3
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);
        }
Beispiel #4
0
        static int obj_desc_pval(Object o_ptr, string buf, int max, int end, bool spoil)
        {
            Bitflag f  = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);
            int     i;

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

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

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

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

            return(end);
        }
Beispiel #5
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);
        }
Beispiel #6
0
        /*
         * Add an object to a real stores inventory.
         *
         * If the object is "worthless", it is thrown away (except in the home).
         *
         * If the object cannot be combined with an object already in the inventory,
         * make a new slot for it, and calculate its "per item" price.  Note that
         * this price will be negative, since the price will not be "fixed" yet.
         * Adding an object to a "fixed" price stack will not change the fixed price.
         *
         * In all cases, return the slot (or -1) where the object was placed
         */
        int carry(Object.Object o_ptr)
        {
            int slot;
            int value, j_value;
            Object.Object j_ptr;

            Object_Kind kind = o_ptr.kind;

            /* Evaluate the object */
            value = o_ptr.value(1, false);

            /* Cursed/Worthless items "disappear" when sold */
            if (value <= 0) return (-1);

            /* Erase the inscription & pseudo-ID bit */
            o_ptr.note = null;

            /* Some item types require maintenance */
            switch (o_ptr.tval)
            {
                /* Refuel lights to the standard amount */
                case TVal.TV_LIGHT:
                {
                    Bitflag f = new Bitflag(Object_Flag.SIZE);
                    o_ptr.object_flags(ref f);

                    if (!f.has(Object_Flag.NO_FUEL.value))
                    {
                        if (o_ptr.sval == SVal.SV_LIGHT_TORCH)
                            o_ptr.timeout = Misc.DEFAULT_TORCH;

                        else if (o_ptr.sval == SVal.SV_LIGHT_LANTERN)
                            o_ptr.timeout = Misc.DEFAULT_LAMP;
                    }

                    break;
                }

                /* Recharge rods */
                case TVal.TV_ROD:
                {
                    o_ptr.timeout = 0;
                    break;
                }

                /* Possibly recharge wands and staves */
                case TVal.TV_STAFF:
                case TVal.TV_WAND:
                {
                    bool recharge = false;

                    /* Recharge without fail if the store normally carries that type */
                    for (int i = 0; i < table_num; i++)
                    {
                        if (table[i] == o_ptr.kind)
                            recharge = true;
                    }

                    if (recharge)
                    {
                        int charges = 0;

                        /* Calculate the recharged number of charges */
                        for (int i = 0; i < o_ptr.number; i++)
                            charges += Random.randcalc(kind.charge, 0, aspect.RANDOMISE);

                        /* Use recharged value only if greater */
                        if (charges > o_ptr.pval[Misc.DEFAULT_PVAL])
                            o_ptr.pval[Misc.DEFAULT_PVAL] = (short)charges;
                    }

                    break;
                }
            }

            /* Check each existing object (try to combine) */
            for (slot = 0; slot < stock_num; slot++)
            {
                /* Get the existing object */
                j_ptr = stock[slot];

                /* Can the existing items be incremented? */
                if (j_ptr.similar(o_ptr, Object.Object.object_stack_t.OSTACK_STORE))
                {
                    /* Absorb (some of) the object */
                    store_object_absorb(ref j_ptr, ref o_ptr);

                    /* All done */
                    return (slot);
                }
            }

            /* No space? */
            if (stock_num >= stock_size) {
                return (-1);
            }

            /* Check existing slots to see if we must "slide" */
            for (slot = 0; slot < stock_num; slot++)
            {
                /* Get that object */
                j_ptr = stock[slot];

                /* Objects sort by decreasing type */
                if (o_ptr.tval > j_ptr.tval) break;
                if (o_ptr.tval < j_ptr.tval) continue;

                /* Objects sort by increasing sval */
                if (o_ptr.sval < j_ptr.sval) break;
                if (o_ptr.sval > j_ptr.sval) continue;

                /* Evaluate that slot */
                j_value = j_ptr.value(1, false);

                /* Objects sort by decreasing value */
                if (value > j_value) break;
                if (value < j_value) continue;
            }

            /* Slide the others up */
            for (int i = stock_num; i > slot; i--)
            {
                stock[i] = stock[i - 1];
                /* Hack -- slide the objects */
                //object_copy(&store.stock[i], &store.stock[i-1]);
            }

            /* More stuff now */
            stock_num++;

            /* Hack -- Insert the new object */
            stock[slot] = o_ptr;
            //object_copy(&store.stock[slot], o_ptr);

            /* Return the location */
            return (slot);
        }
Beispiel #7
0
        static int obj_desc_pval(Object o_ptr, string buf, int max, int end, bool spoil)
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);
            int i;

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

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

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

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

            return end;
        }
Beispiel #8
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;
        }
Beispiel #9
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;
        }
Beispiel #10
0
        /*
         * Acid has hit the player, attempt to affect some armor.
         *
         * Note that the "base armor" of an object never changes.
         *
         * If any armor is damaged (or resists), the player takes less damage.
         */
        static bool minus_ac(Player.Player p)
        {
            Object.Object o_ptr = null;

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

            //char o_name[80];
            string o_name;

            /* Avoid crash during monster power calculations */
            if (p.inventory == null)
            {
                return(false);
            }

            /* Pick a (possibly empty) inventory slot */
            switch (Random.randint1(6))
            {
            case 1: o_ptr = p.inventory[Misc.INVEN_BODY]; break;

            case 2: o_ptr = p.inventory[Misc.INVEN_ARM]; break;

            case 3: o_ptr = p.inventory[Misc.INVEN_OUTER]; break;

            case 4: o_ptr = p.inventory[Misc.INVEN_HANDS]; break;

            case 5: o_ptr = p.inventory[Misc.INVEN_HEAD]; break;

            case 6: o_ptr = p.inventory[Misc.INVEN_FEET]; break;
                //default: Misc.assert(0); //Nick: DA FUQ is this doing here C???
            }

            /* Nothing to damage */
            if (o_ptr.kind == null)
            {
                return(false);
            }

            /* No damage left to be done */
            if (o_ptr.ac + o_ptr.to_a <= 0)
            {
                return(false);
            }

            /* Describe */
            o_name = o_ptr.object_desc(Object.Object.Detail.BASE);
            //object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);

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

            /* Object resists */
            if (f.has(Object.Object_Flag.IGNORE_ACID.value))
            {
                Utilities.msg("Your %s is unaffected!", o_name);

                return(true);
            }

            /* Message */
            Utilities.msg("Your %s is damaged!", o_name);

            /* Damage the item */
            o_ptr.to_a--;

            p.update |= Misc.PU_BONUS;
            p.redraw |= (Misc.PR_EQUIP);

            /* Item was damaged */
            return(true);
        }
Beispiel #11
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;
                }
            }
        }