示例#1
0
        /*
         * Drop all {squelch}able items.
         */
        public static void drop()
        {
            int n;

            /* Scan through the slots backwards */
            for (n = Misc.INVEN_PACK - 1; n >= 0; n--)
            {
                Object.Object o_ptr = Misc.p_ptr.inventory[n];

                /* Skip non-objects and unsquelchable objects */
                if (o_ptr.kind == null)
                {
                    continue;
                }
                if (!item_ok(o_ptr))
                {
                    continue;
                }

                /* Check for !d (no drop) inscription */
                if (!o_ptr.check_for_inscrip("!d") && !o_ptr.check_for_inscrip("!*"))
                {
                    /* We're allowed to drop it. */
                    Object.Object.inven_drop(n, o_ptr.number);
                }
            }

            /* Combine/reorder the pack */
            Misc.p_ptr.notice |= (Misc.PN_COMBINE | Misc.PN_REORDER);
        }
示例#2
0
        /* Put the autoinscription on an object */
        public static int apply_autoinscription(Object.Object o_ptr)
        {
            string o_name = "";             //80
            string note   = get_autoinscription(o_ptr.kind);

            /* Don't inscribe unaware objects */
            if (note == null || note.Length == 0 || !o_ptr.flavor_is_aware())
            {
                return(0);
            }

            /* Don't re-inscribe if it's already inscribed */
            if (o_ptr.note != null)
            {
                return(0);
            }

            /* Get an object description */
            o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);

            if (note == null)
            {
                o_ptr.note = Quark.Add(note);
            }
            else
            {
                o_ptr.note = null;
            }

            Utilities.msg("You autoinscribe {0}.", o_name);

            return(1);
        }
示例#3
0
        /**
         * Check no currently worn items are stopping the action 'c'
         */
        public static bool key_confirm_command(char c)
        {
            int i;

            /* Hack -- Scan equipment */
            for (i = Misc.INVEN_WIELD; i < Misc.INVEN_TOTAL; i++)
            {
                string verify_inscrip = "^" + c;
                int    n;

                Object.Object o_ptr = Misc.p_ptr.inventory[i];
                if (o_ptr.kind == null)
                {
                    continue;
                }

                /* Set up string to look for, e.g. "^d" */
                //verify_inscrip[1] = c;

                /* Verify command */
                n = (o_ptr.check_for_inscrip("^*")?1:0) + (o_ptr.check_for_inscrip(verify_inscrip)?1:0);
                while (n-- != 0)
                {
                    if (!Utilities.get_check("Are you sure? "))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
示例#4
0
        public static void wr_inventory()
        {
            int i;

            /* Write the inventory */
            for (i = 0; i < Misc.ALL_INVEN_TOTAL; i++)
            {
                Object.Object o_ptr = Misc.p_ptr.inventory[i];

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

                /* Dump index */
                wr_u16b((ushort)i);

                /* Dump object */
                wr_item(o_ptr);
            }

            /* Add a sentinel */
            wr_u16b(0xFFFF);
        }
示例#5
0
        /*
         * Init players with some belongings
         *
         * Having an item identifies it and makes the player "aware" of its purpose.
         */
        static void player_outfit(Player.Player p)
        {
            //Object.Object object_type_body = new Object.Object();

            /* Give the player starting equipment */
            for (Start_Item si = Player.Player.instance.Class.start_items; si != null; si = si.next)
            {
                /* Get local object */
                Object.Object i_ptr = new Object.Object();

                /* Prepare the item */
                i_ptr.prep(si.kind, 0, aspect.MINIMISE);
                i_ptr.number = (byte)Random.rand_range(si.min, si.max);
                i_ptr.origin = Origin.BIRTH;

                i_ptr.flavor_aware();
                i_ptr.notice_everything();

                i_ptr.inven_carry(p);
                si.kind.everseen = true;

                /* Deduct the cost of the item from starting cash */
                p.au -= i_ptr.value(i_ptr.number, false);
            }

            /* Sanity check */
            if (p.au < 0)
            {
                p.au = 0;
            }

            /* Now try wielding everything */
            wield_all(p);
        }
示例#6
0
        /*** Squelch code ***/

        /*
         * Squelch the flavor of an object
         */
        public static void object_squelch_flavor_of(Object.Object o_ptr)
        {
            throw new NotImplementedException();
            //if (object_flavor_is_aware(o_ptr))
            //    o_ptr.kind.squelch |= SQUELCH_IF_AWARE;
            //else
            //    o_ptr.kind.squelch |= SQUELCH_IF_UNAWARE;
        }
示例#7
0
        /*
         * Determines if an object is eligible for squelching.
         */
        public static bool item_ok(Object.Object o_ptr)
        {
            byte type;

            if (Misc.p_ptr.unignoring != 0)
            {
                return(false);
            }

            /* Don't squelch artifacts unless marked to be squelched */
            if (o_ptr.artifact != null || o_ptr.check_for_inscrip("!k") || o_ptr.check_for_inscrip("!*"))
            {
                return(false);
            }

            /* Do squelch individual objects that marked ignore */
            if (o_ptr.ignore)
            {
                return(true);
            }

            /* Auto-squelch dead chests */
            if (o_ptr.tval == TVal.TV_CHEST && o_ptr.pval[Misc.DEFAULT_PVAL] == 0)
            {
                return(true);
            }

            /* Do squelching by kind */
            if (o_ptr.flavor_is_aware() ?
                kind_is_squelched_aware(o_ptr.kind) :
                kind_is_squelched_unaware(o_ptr.kind))
            {
                return(true);
            }

            type = (byte)type_of(o_ptr);
            if (type == (int)squelch_type_t.TYPE_MAX)
            {
                return(false);
            }

            /* Squelch items known not to be special */
            if (o_ptr.is_known_not_artifact() && squelch_level[type] == (byte)quality_squelch.SQUELCH_ALL)
            {
                return(true);
            }

            /* Get result based on the feeling and the squelch_level */
            if ((byte)squelch_level_of(o_ptr) <= squelch_level[type])
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#8
0
        /**
         * Small helper function to see if an item seems good, bad or average based on
         * to_h, to_d and to_a.
         *
         * The sign of the return value announces if the object is bad (negative),
         * good (positive) or average (zero).
         */
        static int is_object_good(Object.Object o_ptr)
        {
            int good = 0;

            good += 4 * cmp_object_trait(o_ptr.to_d, o_ptr.kind.to_d);
            good += 2 * cmp_object_trait(o_ptr.to_h, o_ptr.kind.to_h);
            good += 1 * cmp_object_trait(o_ptr.to_a, o_ptr.kind.to_a);
            return(good);
        }
示例#9
0
        static string show_missile_weapon(Object.Object o_ptr)
        {
            Player.Player p_ptr = Player.Player.instance;
            int           hit   = p_ptr.state.dis_to_h;
            int           dam   = 0;

            if (o_ptr.attack_plusses_are_visible())
            {
                hit += o_ptr.to_h;
                dam += o_ptr.to_d;
            }
            return("(" + hit + "," + dam + ")");;
        }
示例#10
0
        /**
         * Browse a given book.
         */
        public static void book_browse(Object.Object o_ptr)
        {
            throw new NotImplementedException();
            //menu_type *m;
            //const char *noun = (p_ptr.class.spell_book == TV_MAGIC_BOOK ?
            //        "spell" : "prayer");

            //m = spell_menu_new(o_ptr, spell_okay_to_browse);
            //if (m) {
            //    spell_menu_browse(m, noun);
            //    spell_menu_destroy(m);
            //} else {
            //    msg("You cannot browse that.");
            //}
        }
示例#11
0
        /*
         * Find the squelch type of the object, or TYPE_MAX if none
         */
        public static squelch_type_t type_of(Object.Object o_ptr)
        {
            /* Find the appropriate squelch group */
            for (int i = 0; i < quality_mapping.Length; i++)
            {
                if ((quality_mapping[i].tval == o_ptr.tval) &&
                    (quality_mapping[i].min_sval <= o_ptr.sval) &&
                    (quality_mapping[i].max_sval >= o_ptr.sval))
                {
                    return(quality_mapping[i].squelch_type);
                }
            }

            return(squelch_type_t.TYPE_MAX);
        }
示例#12
0
        /**
         * Helper function used with ranged_helper by do_cmd_fire.
         */
        public static attack_result make_ranged_shot(Object.Object o_ptr, int y, int x)
        {
            attack_result result = new attack_result(false, 0, 0, "hit");

            Object.Object j_ptr = Misc.p_ptr.inventory[Misc.INVEN_BOW];

            Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]);
            Monster_Race    r_ptr = Misc.r_info[m_ptr.r_idx];

            int bonus   = Misc.p_ptr.state.to_h + o_ptr.to_h + j_ptr.to_h;
            int chance  = Misc.p_ptr.state.skills[(int)Skill.TO_HIT_BOW] + bonus * Misc.BTH_PLUS_ADJ;
            int chance2 = chance - Cave.distance(Misc.p_ptr.py, Misc.p_ptr.px, y, x);

            int  multiplier = Misc.p_ptr.state.ammo_mult;
            Slay best_s_ptr = null;

            /* Did we hit it (penalize distance travelled) */
            if (!test_hit(chance2, r_ptr.ac, m_ptr.ml))
            {
                return(result);
            }

            result.success = true;

            Slay.improve_attack_modifier(o_ptr, m_ptr, ref best_s_ptr, true, false);
            Slay.improve_attack_modifier(j_ptr, m_ptr, ref best_s_ptr, true, false);

            /* If we have a slay, modify the multiplier appropriately */
            if (best_s_ptr != null)
            {
                result.hit_verb = best_s_ptr.range_verb;
                multiplier     += best_s_ptr.mult;
            }

            /* Apply damage: multiplier, slays, criticals, bonuses */
            result.dmg  = Random.damroll(o_ptr.dd, o_ptr.ds);
            result.dmg += o_ptr.to_d + j_ptr.to_d;
            result.dmg *= multiplier;
            result.dmg  = critical_shot(o_ptr.weight, o_ptr.to_h, result.dmg, ref result.msg_type);

            Misc.p_ptr.inventory[Misc.INVEN_BOW].notice_attack_plusses();

            return(result);
        }
示例#13
0
        public static void wr_objects()
        {
            int i;

            if (Misc.p_ptr.is_dead)
            {
                return;
            }

            /* Total objects */
            wr_u16b((ushort)Misc.o_max);

            /* Dump the objects */
            for (i = 1; i < Misc.o_max; i++)
            {
                Object.Object o_ptr = Object.Object.byid((short)i);

                /* Dump it */
                wr_item(o_ptr);
            }
        }
示例#14
0
        /*
         * Check to see if the player can use a rod/wand/staff/activatable object.
         */
        static int check_devices(Object.Object o_ptr)
        {
            throw new NotImplementedException();
            //int fail;
            //const char *action;
            //const char *what = null;

            ///* Get the right string */
            //switch (o_ptr.tval)
            //{
            //    case TV_ROD:   action = "zap the rod";   break;
            //    case TV_WAND:  action = "use the wand";  what = "wand";  break;
            //    case TV_STAFF: action = "use the staff"; what = "staff"; break;
            //    default:       action = "activate it";  break;
            //}

            ///* Figure out how hard the item is to use */
            //fail = get_use_device_chance(o_ptr);

            ///* Roll for usage */
            //if (randint1(1000) < fail)
            //{
            //    flush();
            //    msg("You failed to %s properly.", action);
            //    return false;
            //}

            ///* Notice empty staffs */
            //if (what && o_ptr.pval[DEFAULT_PVAL] <= 0)
            //{
            //    flush();
            //    msg("The %s has no charges left.", what);
            //    o_ptr.ident |= (IDENT_EMPTY);
            //    return false;
            //}

            //return true;
        }
示例#15
0
        /*
         * Helper function: create an item with the given tval,sval pair, add it to the
         * store st.  Return the slot in the inventory.
         */
        int create_item(Object_Kind kind)
        {
            Object.Object obj = new Object.Object();

            /* Create a new object of the chosen kind */
            obj.prep(kind, 0, aspect.RANDOMISE);

            /* Item belongs to a store */
            obj.ident |= Object.Object.IDENT_STORE;
            obj.origin = Origin.STORE;

            /* Attempt to carry the object */
            return carry(obj);
        }
示例#16
0
        /*
         * Creates a random object and gives it to store 'st'
         */
        bool create_random()
        {
            int tries, level;

            Object.Object i_ptr;
            //Object.Object object_type_body;

            int min_level, max_level;

            /* Decide min/max levels */
            if (sidx == STORE.B_MARKET) {
                min_level = Misc.p_ptr.max_depth + 5;
                max_level = Misc.p_ptr.max_depth + 20;
            } else {
                min_level = 1;
                max_level = STORE_OBJ_LEVEL + Math.Max(Misc.p_ptr.max_depth - 20, 0);
            }

            if (min_level > 55) min_level = 55;
            if (max_level > 70) max_level = 70;

            /* Consider up to six items */
            for (tries = 0; tries < 6; tries++)
            {
                Object_Kind kind;

                /* Work out the level for objects to be generated at */
                level = Random.rand_range(min_level, max_level);

                /* Black Markets have a random object, of a given level */
                if (sidx == STORE.B_MARKET)
                    kind = Object.Object.get_obj_num(level, false);
                else
                    kind = get_choice();

                /*** Pre-generation filters ***/

                /* No chests in stores XXX */
                if (kind.tval == TVal.TV_CHEST) continue;

                /*** Generate the item ***/

                /* Get local object */
                i_ptr = new Object.Object();
                //i_ptr = object_type_body;

                /* Create a new object of the chosen kind */
                i_ptr.prep(kind, level, aspect.RANDOMISE);

                /* Apply some "low-level" magic (no artifacts) */
                i_ptr.apply_magic(level, false, false, false);

                /* Reject if item is 'damaged' (i.e. negative mods) */
                switch (i_ptr.tval)
                {
                    case TVal.TV_DIGGING:
                    case TVal.TV_HAFTED:
                    case TVal.TV_POLEARM:
                    case TVal.TV_SWORD:
                    case TVal.TV_BOW:
                    case TVal.TV_SHOT:
                    case TVal.TV_ARROW:
                    case TVal.TV_BOLT:
                    {
                        if ((i_ptr.to_h < 0) || (i_ptr.to_d < 0))
                            continue;
                        if (i_ptr.to_a < 0) continue;
                        break;
                    }

                    case TVal.TV_DRAG_ARMOR:
                    case TVal.TV_HARD_ARMOR:
                    case TVal.TV_SOFT_ARMOR:
                    case TVal.TV_SHIELD:
                    case TVal.TV_HELM:
                    case TVal.TV_CROWN:
                    case TVal.TV_CLOAK:
                    case TVal.TV_GLOVES:
                    case TVal.TV_BOOTS:
                    {
                        if (i_ptr.to_a < 0) continue;
                        break;
                    }
                }

                /* The object is "known" and belongs to a store */
                i_ptr.ident |= Object.Object.IDENT_STORE;
                i_ptr.origin = Origin.STORE;

                /*** Post-generation filters ***/

                /* Black markets have expensive tastes */
                if ((sidx == STORE.B_MARKET) && !black_market_ok(i_ptr))
                    continue;

                /* No "worthless" items */
                if (i_ptr.value(1, false) < 1) continue;

                /* Mass produce and/or apply discount */
                mass_produce(i_ptr);

                /* Attempt to carry the object */
                carry(i_ptr);

                /* Definitely done */
                return true;
            }

            return false;
        }
示例#17
0
        public static void see_floor_items(Game_Event.Event_Type type, Game_Event data, object user)
        {
            int py = Misc.p_ptr.py;
            int px = Misc.p_ptr.px;

            int floor_num = 0;

            int[] floor_list = new int[Misc.MAX_FLOOR_STACK + 1];
            bool  blind      = ((Misc.p_ptr.timed[(int)Timed_Effect.BLIND] != 0) || (Cave.no_light()));

            string p          = "see";
            int    can_pickup = 0;
            int    i;

            /* Scan all marked objects in the grid */
            floor_num = Object.Object.scan_floor(floor_list, floor_list.Length, py, px, 0x03);
            if (floor_num == 0)
            {
                return;
            }

            for (i = 0; i < floor_num; i++)
            {
                can_pickup += Object.Object.byid((short)floor_list[i]).inven_carry_okay()?1:0;
            }

            /* One object */
            if (floor_num == 1)
            {
                /* Get the object */
                Object.Object o_ptr = Object.Object.byid((short)floor_list[0]);
                //char o_name[80];
                string o_name = null;

                if (can_pickup == 0)
                {
                    p = "have no room for";
                }
                else if (blind)
                {
                    p = "feel";
                }

                /* Describe the object.  Less detail if blind. */
                if (blind)
                {
                    o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.BASE);
                }
                else
                {
                    o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);
                }

                /* Message */
                Utilities.message_flush();
                Utilities.msg("You {0} {1}.", p, o_name);
            }
            else
            {
                ui_event e;

                if (can_pickup == 0)
                {
                    p = "have no room for the following objects";
                }
                else if (blind)
                {
                    p = "feel something on the floor";
                }

                throw new NotImplementedException();
                /* Display objects on the floor */
                //screen_save();
                //show_floor(floor_list, floor_num, (OLIST_WEIGHT));
                //prt(format("You %s: ", p), 0, 0);

                ///* Wait for it.  Use key as next command. */
                //e = inkey_ex();
                //Term_event_push(&e);

                ///* Restore screen */
                //screen_load();
            }
        }
示例#18
0
        /*
         * Buy an object from a store
         */
        static bool store_purchase(int item)
        {
            int amt, num;
            int price;

            Object.Object o_ptr;

            //object_type object_type_body;
            Object.Object i_ptr = new Object.Object();

            //char o_name[80];
            string o_name;

            Store store = current_store();

            if (store == null) {
                Utilities.msg("You cannot purchase items when not in a store.");
                return false;
            }

            /* Get the actual object */
            o_ptr = store.stock[item];
            if (item < 0) return false;

            /* Clear all current messages */
            Term.msg_flag = false;
            Utilities.prt("", 0, 0);

            if (store.sidx == STORE.HOME) {
                amt = o_ptr.number;
            } else {
                /* Price of one */
                price = price_item(o_ptr, false, 1);

                /* Check if the player can afford any at all */
                if ((uint)Misc.p_ptr.au < (uint)price)
                {
                    /* Tell the user */
                    Utilities.msg("You do not have enough gold for this item.");

                    /* Abort now */
                    return false;
                }

                /* Work out how many the player can afford */
                amt = Misc.p_ptr.au / price;
                if (amt > o_ptr.number) amt = o_ptr.number;

                /* Double check for wands/staves */
                if ((Misc.p_ptr.au >= price_item(o_ptr, false, amt+1)) && (amt < o_ptr.number))
                    amt++;

            }

            /* Find the number of this item in the inventory */
            if (!o_ptr.flavor_is_aware())
                num = 0;
            else
                num = find_inven(o_ptr);

            o_name = String.Format("{0} how many{1}? (max {2}) ",
                    (store.sidx == STORE.HOME) ? "Take" : "Buy",
                    num != 0 ? String.Format(" (you have {0})", num) : "", amt);

            /* Get a quantity */
            amt = Utilities.get_quantity(o_name, amt);

            /* Allow user abort */
            if (amt <= 0) return false;

            /* Get desired object */
            Object.Object.copy_amt(ref i_ptr, o_ptr, amt);

            /* Ensure we have room */
            if (!i_ptr.inven_carry_okay())
            {
                Utilities.msg("You cannot carry that many items.");
                return false;
            }

            /* Describe the object (fully) */
            o_name = i_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);

            /* Attempt to buy it */
            if (store.sidx != STORE.HOME)
            {
                bool response;

                /* Extract the price for the entire stack */
                price = price_item(i_ptr, false, i_ptr.number);

                Utilities.screen_save();

                /* Show price */
                Utilities.prt(String.Format("Price: {0}", price), 1, 0);

                /* Confirm purchase */
                response = store_get_check(String.Format("Buy {0}? [ESC, any other key to accept]", o_name));
                Utilities.screen_load();

                /* Negative response, so give up */
                if (!response) return false;

                Game_Command.insert(Command_Code.BUY);
                Game_Command.get_top().set_arg_choice(0, item);
                Game_Command.get_top().set_arg_number(1, amt);
            }

            /* Home is much easier */
            else
            {
                Game_Command.insert(Command_Code.RETRIEVE);
                Game_Command.get_top().set_arg_choice(0, item);
                Game_Command.get_top().set_arg_number(1, amt);
            }

            /* Not kicked out */
            return true;
        }
示例#19
0
        /*
         * Init players with some belongings
         *
         * Having an item identifies it and makes the player "aware" of its purpose.
         */
        static void player_outfit(Player.Player p)
        {
            //Object.Object object_type_body = new Object.Object();

            /* Give the player starting equipment */
            for (Start_Item si = Player.Player.instance.Class.start_items; si != null; si = si.next)
            {
                /* Get local object */
                Object.Object i_ptr = new Object.Object();

                /* Prepare the item */
                i_ptr.prep(si.kind, 0, aspect.MINIMISE);
                i_ptr.number = (byte)Random.rand_range(si.min, si.max);
                i_ptr.origin = Origin.BIRTH;

                i_ptr.flavor_aware();
                i_ptr.notice_everything();

                i_ptr.inven_carry(p);
                si.kind.everseen = true;

                /* Deduct the cost of the item from starting cash */
                p.au -= i_ptr.value(i_ptr.number, false);
            }

            /* Sanity check */
            if (p.au < 0)
                p.au = 0;

            /* Now try wielding everything */
            wield_all(p);
        }
示例#20
0
        /**
         * Try to wield everything wieldable in the inventory.
         */
        static void wield_all(Player.Player p)
        {
            Object.Object o_ptr;
            Object.Object i_ptr;
            //Object.Object object_type_body;

            int slot;
            int item;
            int num;
            bool is_ammo;

            /* Scan through the slots backwards */
            for (item = Misc.INVEN_PACK - 1; item >= 0; item--)
            {
                o_ptr = p.inventory[item];
                is_ammo = o_ptr.is_ammo();

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

                /* Make sure we can wield it */
                slot = o_ptr.wield_slot();
                if (slot < Misc.INVEN_WIELD) continue;

                i_ptr = p.inventory[slot];
                if (i_ptr.kind != null && (!is_ammo ||(is_ammo && !o_ptr.similar(i_ptr, Object.Object.object_stack_t.OSTACK_PACK))))
                    continue;

                /* Figure out how much of the item we'll be wielding */
                num = is_ammo ? o_ptr.number : 1;

                /* Get local object */
                i_ptr = new Object.Object();
                i_ptr = o_ptr.copy();
                //This entire bit was uber shadey... Rewrote above
                ////i_ptr = object_type_body;
                //p.inventory[slot] = o_ptr; //object_copy(i_ptr, o_ptr); //This might not work...
                //i_ptr = o_ptr;  //If wonky equips happen, check here

                /* Modify quantity */
                i_ptr.number = (byte)num;

                /* Decrease the item (from the pack) */
                Object.Object.inven_item_increase(item, -num);
                Object.Object.inven_item_optimize(item);

                /* Get the wield slot */
                //o_ptr = p.inventory[slot];

                /* Wear the new stuff */
                //object_copy(o_ptr, i_ptr);
                p.inventory[slot] = i_ptr;

                /* Increase the weight */
                p.total_weight += i_ptr.weight * i_ptr.number;

                /* Increment the equip counter by hand */
                p.equip_cnt++;
            }

            Object.Object.save_quiver_size(p);

            return;
        }
示例#21
0
        ///**
        // * Place random stairs at (x, y).
        // */
        //static void place_random_stairs(Cave c, int y, int x) {
        //    int feat = randint0(100) < 50 ? FEAT_LESS : FEAT_MORE;
        //    if (cave_canputitem(c, y, x))
        //        place_stairs(c, y, x, feat);
        //}
        /**
         * Place a random object at (x, y).
         */
        public static void place_object(Cave c, int y, int x, int level, bool good, bool great, Origin origin)
        {
            int rating = 0;
            Object.Object otype;

            Misc.assert(cave_in_bounds(c, y, x));

            if (!cave_canputitem(c, y, x)) return;

            otype = new Object.Object();
            //object_wipe(&otype);
            if (!Object.Object.make_object(c, ref otype, level, good, great, ref rating)) return;

            otype.origin = origin;
            otype.origin_depth = (byte)c.depth;

            /* Give it to the floor */
            /* XXX Should this be done in floor_carry? */
            if (Object.Object.floor_carry(c, y, x, otype) == 0) {
                if (otype.artifact != null)
                    otype.artifact.created = false;
                return;
            } else {
                if (otype.artifact != null)
                    c.good_item = true;
                c.obj_rating += (uint)rating;
            }
        }
示例#22
0
        /**
         * This is a helper function used by do_cmd_throw and do_cmd_fire.
         *
         * It abstracts out the projectile path, display code, identify and clean up
         * logic, while using the 'attack' parameter to do work particular to each
         * kind of attack.
         */
        public static void ranged_helper(int item, int dir, int range, int shots, ranged_attack attack)
        {
            /* Get the ammo */
            Object.Object o_ptr = Object.Object.object_from_item_idx(item);

            int i, j;
            ConsoleColor missile_attr = o_ptr.object_attr();
            char missile_char = o_ptr.object_char();

            //object_type object_type_body;
            Object.Object i_ptr = new Object.Object();//&object_type_body;

            //char o_name[80];
            string o_name;

            int path_n;
            List<ushort> path_g = new List<ushort>();//[256];

            int msec = Player.Player_Other.instance.delay_factor;

            /* Start at the player */
            int x = Misc.p_ptr.px;
            int y = Misc.p_ptr.py;

            /* Predict the "target" location */
            short ty = (short)(y + 99 * Misc.ddy[dir]);
            short tx = (short)(x + 99 * Misc.ddx[dir]);

            bool hit_target = false;

            /* Check for target validity */
            if ((dir == 5) && Target.okay()) {
                int taim;
                //char msg[80];
                string msg;
                Target.get(out tx, out ty);
                taim = Cave.distance(y, x, ty, tx);
                if (taim > range) {
                    msg = String.Format("Target out of range by {0} squares. Fire anyway? ", taim - range);
                    if (!Utilities.get_check(msg)) return;
                }
            }

            /* Sound */
            //sound(MSG_SHOOT); //later

            o_ptr.notice_on_firing();

            /* Describe the object */
            o_name = o_ptr.object_desc(Object.Object.Detail.FULL | Object.Object.Detail.SINGULAR);

            /* Actually "fire" the object -- Take a partial turn */
            Misc.p_ptr.energy_use = (short)(100 / shots);

            /* Calculate the path */
            path_n = Cave.project_path(out path_g, range, y, x, ty, tx, 0);

            /* Hack -- Handle stuff */
            Misc.p_ptr.handle_stuff();

            /* Start at the player */
            x = Misc.p_ptr.px;
            y = Misc.p_ptr.py;

            /* Project along the path */
            for (i = 0; i < path_n; ++i) {
                int ny = Cave.GRID_Y(path_g[i]);
                int nx = Cave.GRID_X(path_g[i]);

                /* Hack -- Stop before hitting walls */
                if (!Cave.cave_floor_bold(ny, nx)) break;

                /* Advance */
                x = nx;
                y = ny;

                /* Only do visuals if the player can "see" the missile */
                if (Cave.player_can_see_bold(y, x)) {
                    Cave.print_rel(missile_char, missile_attr, y, x);
                    Cave.move_cursor_relative(y, x);

                    Term.fresh();
                    if (Misc.p_ptr.redraw != 0) Misc.p_ptr.redraw_stuff();

                    Term.xtra(TERM_XTRA.DELAY, msec);
                    Cave.cave_light_spot(Cave.cave, y, x);

                    Term.fresh();
                    if (Misc.p_ptr.redraw != 0) Misc.p_ptr.redraw_stuff();
                } else {
                    /* Delay anyway for consistency */
                    Term.xtra(TERM_XTRA.DELAY, msec);
                }

                /* Handle monster */
                if (Cave.cave.m_idx[y][x] > 0) break;
            }

            /* Try the attack on the monster at (x, y) if any */
            if (Cave.cave.m_idx[y][x] > 0) {
                Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]);
                Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];
                bool visible = m_ptr.ml;

                bool fear = false;
                //char m_name[80];
                string m_name;
                string note_dies = r_ptr.monster_is_unusual() ? " is destroyed." : " dies.";

                attack_result result = attack(o_ptr, y, x);
                int dmg = result.dmg;
                Message_Type msg_type = result.msg_type;
                string hit_verb = result.hit_verb;

                if (result.success) {
                    hit_target = true;

                    /* Get "the monster" or "it" */
                    m_name = m_ptr.monster_desc(0);

                    o_ptr.notice_attack_plusses();

                    /* No negative damage; change verb if no damage done */
                    if (dmg <= 0) {
                        dmg = 0;
                        hit_verb = "fail to harm";
                    }

                    if (!visible) {
                        /* Invisible monster */
                        Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} finds a mark.", o_name);
                    } else {
                        /* Visible monster */
                        if ((Message_Type)msg_type == Message_Type.MSG_SHOOT_HIT)
                            Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} {1} {2}.", o_name, hit_verb, m_name);
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GOOD) {
                            Utilities.msgt(Message_Type.MSG_HIT_GOOD, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                "It was a good hit!");
                        } else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GREAT) {
                            Utilities.msgt(Message_Type.MSG_HIT_GREAT, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                 "It was a great hit!");
                        } else if ((Message_Type)msg_type == Message_Type.MSG_HIT_SUPERB) {
                            Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                 "It was a superb hit!");
                        }

                        /* Track this monster */
                        if (m_ptr.ml) Cave.monster_race_track(m_ptr.r_idx);
                        if (m_ptr.ml) Cave.health_track(Misc.p_ptr, Cave.cave.m_idx[y][x]);
                    }

                    /* Complex message */
                    if (Misc.p_ptr.wizard)
                        Utilities.msg("You do {0} (out of {1}) damage.", dmg, m_ptr.hp);

                    /* Hit the monster, check for death */
                    if (!Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, note_dies)) {
                        Monster_Message.message_pain(Cave.cave.m_idx[y][x], dmg);
                        if (fear && m_ptr.ml)
                            Monster_Message.add_monster_message(m_name, Cave.cave.m_idx[y][x], MON_MSG.FLEE_IN_TERROR, true);
                    }
                }
            }

            /* Obtain a local object */
            i_ptr = o_ptr.copy();
            i_ptr.split(o_ptr, 1);

            /* See if the ammunition broke or not */
            j = i_ptr.breakage_chance(hit_target);

            /* Drop (or break) near that location */
            Object.Object.drop_near(Cave.cave, i_ptr, j, y, x, true);

            if (item >= 0) {
                /* The ammo is from the inventory */
                Object.Object.inven_item_increase(item, -1);
                Object.Object.inven_item_describe(item);
                Object.Object.inven_item_optimize(item);
            } else {
                /* The ammo is from the floor */
                Object.Object.floor_item_increase(0 - item, -1);
                Object.Object.floor_item_optimize(0 - item);
            }
        }
示例#23
0
        static void display_resistance_panel(player_flag_record[] resists, int size, Region bounds)
        {
            Player.Player p_ptr = Player.Player.instance;
            int           col   = bounds.col;
            int           row   = bounds.row;

            Term.putstr(col, row++, RES_COLS, ConsoleColor.White, "      abcdefghijkl@");
            for (int i = 0; i < size - 3; i++, row++)
            {
                ConsoleColor name_attr = ConsoleColor.White;
                Term.gotoxy(col + 6, row);
                /* repeated extraction of flags is inefficient but more natural */
                for (int j = Misc.INVEN_WIELD; j <= Misc.INVEN_TOTAL; j++)
                {
                    Object.Object o_ptr = p_ptr.inventory[j];
                    Bitflag       f     = new Bitflag(Object_Flag.SIZE);

                    ConsoleColor[] alternatingcols = new ConsoleColor[] { ConsoleColor.Gray, ConsoleColor.DarkGray };
                    ConsoleColor   attr            = alternatingcols[j % 2];        /* alternating columns */
                    char           sym             = '.';

                    bool res, imm, vuln;

                    /* Wipe flagset */
                    f.wipe();

                    if (j < Misc.INVEN_TOTAL && o_ptr.kind != null)
                    {
                        o_ptr.object_flags_known(ref f);
                    }
                    else if (j == Misc.INVEN_TOTAL)
                    {
                        Player.Player.player_flags(ref f);

                        /* If the race has innate infravision/digging, force the corresponding flag
                         * here.  If we set it in player_flags(), then all callers of that
                         * function will think the infravision is caused by equipment. */
                        if (p_ptr.Race.infra > 0)
                        {
                            f.on(Object_Flag.INFRA.value);
                        }
                        if (p_ptr.Race.r_skills[(int)Skill.DIGGING] > 0)
                        {
                            f.on(Object_Flag.TUNNEL.value);
                        }
                    }

                    res  = f.has(resists[i].res_flag.value);
                    imm  = f.has(resists[i].im_flag.value);
                    vuln = f.has(resists[i].vuln_flag.value);

                    if (imm)
                    {
                        name_attr = ConsoleColor.DarkGreen;
                    }
                    else if (res && name_attr == ConsoleColor.White)
                    {
                        name_attr = ConsoleColor.Cyan;
                    }

                    if (vuln)
                    {
                        sym = '-';
                    }
                    else if (imm)
                    {
                        sym = '*';
                    }
                    else if (res)
                    {
                        sym = '+';
                    }
                    else if ((j < Misc.INVEN_TOTAL) && o_ptr.kind != null &&
                             !o_ptr.object_flag_is_known(resists[i].res_flag.value))
                    {
                        sym = '?';
                    }
                    Term.addch(attr, sym);
                }
                Term.putstr(col, row, 6, name_attr, resists[i].name.ToString());
            }
            Term.putstr(col, row++, RES_COLS, ConsoleColor.White, "      abcdefghijkl@");
            /* Equippy */
            display_player_equippy(row++, col + 6);
        }
示例#24
0
        /*
         * Request a game command from the uI and carry out whatever actions
         * go along with it.
         */
        public static void process_command(cmd_context ctx, bool no_request)
        {
            Game_Command cmd = new Game_Command();

            /* Reset so that when selecting items, we look in the default location */
            Misc.p_ptr.command_wrk = 0;

            /* If we've got a command to process, do it. */
            if (get(ctx, ref cmd, !no_request) != null)             //Was ==null...
            {
                int oldrepeats = cmd.nrepeats;
                int idx        = cmd_idx(cmd.command);
                int i;

                if (idx == -1)
                {
                    return;
                }

                for (i = 0; i < item_selector.Length; i++)
                {
                    item_selector_type itms = item_selector[i];

                    if (itms.command != cmd.command)
                    {
                        continue;
                    }

                    if (!cmd.arg_present[0])
                    {
                        int item = 0;

                        Misc.item_tester_hook = itms.filter;
                        if (!Object.Object.get_item(ref item, itms.prompt, itms.noop, cmd.command, itms.mode))
                        {
                            return;
                        }

                        cmd.set_arg_item(0, item);
                    }
                }

                /* XXX avoid dead objects from being re-used on repeat.
                 * this needs to be expanded into a general safety-check
                 * on args */
                if ((game_cmds[idx].arg_type[0] == cmd_arg_type.arg_ITEM) && cmd.arg_present[0])
                {
                    Object.Object o_ptr = Object.Object.object_from_item_idx(cmd.arg[0].value);
                    if (o_ptr.kind == null)
                    {
                        return;
                    }
                }

                /* Do some sanity checking on those arguments that might have
                 * been declared as "unknown", such as directions and targets. */
                switch (cmd.command)
                {
                case Command_Code.INSCRIBE:
                {
                    throw new NotImplementedException();
                    //char o_name[80];
                    //char tmp[80] = "";

                    //object_type *o_ptr = object_from_item_idx(cmd.arg[0].item);

                    //object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);
                    //msg("Inscribing %s.", o_name);
                    //message_flush();

                    ///* Use old inscription */
                    //if (o_ptr.note)
                    //    strnfmt(tmp, sizeof(tmp), "%s", quark_str(o_ptr.note));

                    ///* Get a new inscription (possibly empty) */
                    //if (!get_string("Inscription: ", tmp, sizeof(tmp)))
                    //    return;

                    //cmd_set_arg_string(cmd, 1, tmp);
                    //break;
                }

                case Command_Code.OPEN:
                {
                    throw new NotImplementedException();
                    //if (Option.easy_open.value && (!cmd.arg_present[0] ||
                    //        cmd.arg[0].value == (int)Direction.UNKNOWN))
                    //{
                    //    int y, x;
                    //    int n_closed_doors, n_locked_chests;

                    //    throw new NotImplementedException();
                    //    n_closed_doors = count_feats(&y, &x, cave_iscloseddoor, false);
                    //    n_locked_chests = count_chests(&y, &x, false);

                    //    if (n_closed_doors + n_locked_chests == 1)
                    //        cmd_set_arg_direction(cmd, 0, coords_to_dir(y, x));
                    //}

                    //goto get_dir;
                }

                case Command_Code.CLOSE:
                {
                    throw new NotImplementedException();
                    //if (OPT(easy_open) && (!cmd.arg_present[0] ||
                    //        cmd.arg[0].direction == DIR_UNKNOWN))
                    //{
                    //    int y, x;

                    //    /* Count open doors */
                    //    if (count_feats(&y, &x, cave_isopendoor, false) == 1)
                    //        cmd_set_arg_direction(cmd, 0, coords_to_dir(y, x));
                    //}

                    //goto get_dir;
                }

                case Command_Code.DISARM:
                {
                    throw new NotImplementedException();
                    //if (OPT(easy_open) && (!cmd.arg_present[0] ||
                    //        cmd.arg[0].direction == DIR_UNKNOWN))
                    //{
                    //    int y, x;
                    //    int n_visible_traps, n_trapped_chests;

                    //    n_visible_traps = count_feats(&y, &x, cave_isknowntrap, true);
                    //    n_trapped_chests = count_chests(&y, &x, true);

                    //    if (n_visible_traps + n_trapped_chests == 1)
                    //        cmd_set_arg_direction(cmd, 0, coords_to_dir(y, x));
                    //}

                    //goto get_dir;
                }

                case Command_Code.TUNNEL:
                case Command_Code.WALK:
                case Command_Code.RUN:
                case Command_Code.JUMP:
                case Command_Code.BASH:
                case Command_Code.ALTER:
                case Command_Code.JAM:
                {
get_dir:
                    /* Direction hasn't been specified, so we ask for one. */
                    if (!cmd.arg_present[0] || cmd.arg[0].value == (int)Direction.UNKNOWN)
                    {
                        int dir;
                        if (!Xtra2.get_rep_dir(out dir))
                        {
                            return;
                        }


                        cmd.set_arg_direction(0, dir);
                    }

                    break;
                }

                case Command_Code.DROP:
                {
                    throw new NotImplementedException();
                    //if (!cmd.arg_present[1])
                    //{
                    //    object_type *o_ptr = object_from_item_idx(cmd.arg[0].item);
                    //    int amt = get_quantity(null, o_ptr.number);
                    //    if (amt <= 0)
                    //        return;

                    //    cmd_set_arg_number(cmd, 1, amt);
                    //}

                    //break;
                }

                /*
                 * These take an item number and a  "target" as arguments,
                 * though a target isn't always actually needed, so we'll
                 * only prompt for it via callback if the item being used needs it.
                 */
                case Command_Code.USE_WAND:
                case Command_Code.USE_ROD:
                case Command_Code.QUAFF:
                case Command_Code.ACTIVATE:
                case Command_Code.READ_SCROLL:
                case Command_Code.FIRE:
                case Command_Code.THROW:
                {
                    bool          get_target = false;
                    Object.Object o_ptr      = Object.Object.object_from_item_idx(cmd.arg[0].value);

                    /* If we couldn't resolve the item, then abort this */
                    if (o_ptr.kind == null)
                    {
                        break;
                    }

                    /* Thrown objects always need an aim, others might, depending
                     * on the object */
                    if (o_ptr.needs_aim() || cmd.command == Command_Code.THROW)
                    {
                        if (!cmd.arg_present[1])
                        {
                            get_target = true;
                        }
                        else if (cmd.arg[1].value == (int)Direction.UNKNOWN)
                        {
                            get_target = true;
                        }
                        else if (cmd.arg[1].value == (int)Direction.TARGET && !Target.okay())
                        {
                            get_target = true;
                        }
                    }

                    cmd.arg[1]       = new cmd_arg();
                    cmd.arg[1].value = 0;

                    if (get_target && !Xtra2.get_aim_dir(ref cmd.arg[1].value))
                    {
                        return;
                    }

                    Misc.p_ptr.confuse_dir(ref cmd.arg[1].value, false);
                    cmd.arg_present[1] = true;

                    break;
                }

                /* This takes a choice and a direction. */
                case Command_Code.CAST:
                {
                    throw new NotImplementedException();
                    //bool get_target = false;

                    //if (spell_needs_aim(Misc.p_ptr.Class.spell_book, cmd.arg[0].choice))
                    //{
                    //    if (!cmd.arg_present[1])
                    //        get_target = true;

                    //    if (cmd.arg[1].direction == DIR_UNKNOWN)
                    //        get_target = true;

                    //    if (cmd.arg[1].direction == DIR_TARGET && !target_okay())
                    //        get_target = true;
                    //}

                    //if (get_target && !get_aim_dir(&cmd.arg[1].direction))
                    //        return;

                    //player_confuse_dir(p_ptr, &cmd.arg[1].direction, false);
                    //cmd.arg_present[1] = true;

                    //break;
                }

                case Command_Code.WIELD:
                {
                    Object.Object o_ptr = Object.Object.object_from_item_idx(cmd.arg[0].value);
                    int           slot  = o_ptr.wield_slot();

                    /* Usually if the slot is taken we'll just replace the item in the slot,
                     * but in some cases we need to ask the user which slot they actually
                     * want to replace */
                    if (Misc.p_ptr.inventory[slot].kind != null)
                    {
                        if (o_ptr.tval == Object.TVal.TV_RING)
                        {
                            string q = "Replace which ring? ";
                            string s = "Error in obj_wield, please report";
                            Misc.item_tester_hook = Object.Object.obj_is_ring;
                            if (!Object.Object.get_item(ref slot, q, s, Command_Code.WIELD, Misc.USE_EQUIP))
                            {
                                return;
                            }
                        }

                        if (o_ptr.is_ammo() &&
                            !Misc.p_ptr.inventory[slot].similar(o_ptr, Object.Object.object_stack_t.OSTACK_QUIVER))
                        {
                            string q = "Replace which ammunition? ";
                            string s = "Error in obj_wield, please report";
                            Misc.item_tester_hook = Object.Object.obj_is_ammo;
                            if (!Object.Object.get_item(ref slot, q, s, Command_Code.WIELD, Misc.USE_EQUIP))
                            {
                                return;
                            }
                        }
                    }

                    /* Set relevant slot */
                    cmd.set_arg_number(1, slot);

                    break;
                }

                default:
                {
                    /* I can see the point of the compiler warning, but still... */
                    break;
                }
                }

                /* Command repetition */
                if (game_cmds[idx].repeat_allowed)
                {
                    /* Auto-repeat only if there isn't already a repeat length. */
                    if (game_cmds[idx].nrepeats > 0 && cmd.nrepeats == 0)
                    {
                        Game_Command.set_repeat(game_cmds[idx].nrepeats);
                    }
                }
                else
                {
                    cmd.nrepeats = 0;
                    repeating    = false;
                }

                /*
                 * The command gets to unset this if it isn't appropriate for
                 * the user to repeat it.
                 */
                repeat_prev_allowed = true;

                if (game_cmds[idx].fn != null)
                {
                    game_cmds[idx].fn(cmd.command, cmd.arg);
                }

                /* If the command hasn't changed nrepeats, count this execution. */
                if (cmd.nrepeats > 0 && oldrepeats == Game_Command.get_nrepeats())
                {
                    Game_Command.set_repeat(oldrepeats - 1);
                }
            }
        }
示例#25
0
        /*
         * Special display, part 2c
         *
         * How to print out the modifications and sustains.
         * Positive mods with no sustain will be light green.
         * Positive mods with a sustain will be dark green.
         * Sustains (with no modification) will be a dark green 's'.
         * Negative mods (from a curse) will be red.
         * Huge mods (>9), like from MICoMorgoth, will be a '*'
         * No mod, no sustain, will be a slate '.'
         */
        static void display_player_sust_info()
        {
            int j, stat;

            Player.Player p_ptr = Player.Player.instance;

            Bitflag f = new Bitflag(Object_Flag.SIZE);

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

            ConsoleColor a;
            char         c;


            /* Row */
            int row = 2;

            /* Column */
            int col = 26;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                /* Advance */
                col++;
            }

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

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

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

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

            /* Column */
            col = 26;

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

            /* Equippy */
            display_player_equippy(row + 7, col);
        }
示例#26
0
        /*
         * Write an "item" record
         */
        static void wr_item(Object.Object o_ptr)
        {
            int i, j;

            wr_u16b(0xffff);
            wr_byte(Savefile.ITEM_VERSION);

            wr_s16b(0);

            /* Location */
            wr_byte(o_ptr.iy);
            wr_byte(o_ptr.ix);

            wr_byte(o_ptr.tval);
            wr_byte(o_ptr.sval);

            for (i = 0; i < Misc.MAX_PVALS; i++)
            {
                wr_s16b(o_ptr.pval[i]);
            }
            wr_byte(o_ptr.num_pvals);

            wr_byte(0);

            wr_byte(o_ptr.number);
            wr_s16b(o_ptr.weight);

            if (o_ptr.artifact != null)
            {
                wr_byte((byte)o_ptr.artifact.aidx);
            }
            else
            {
                wr_byte(0);
            }

            if (o_ptr.ego != null)
            {
                wr_byte((byte)o_ptr.ego.eidx);
            }
            else
            {
                wr_byte(0);
            }

            wr_s16b(o_ptr.timeout);

            wr_s16b(o_ptr.to_h);
            wr_s16b(o_ptr.to_d);
            wr_s16b(o_ptr.to_a);
            wr_s16b(o_ptr.ac);
            wr_byte(o_ptr.dd);
            wr_byte(o_ptr.ds);

            wr_u16b((ushort)o_ptr.ident);

            wr_byte(o_ptr.marked);

            wr_byte((byte)o_ptr.origin);
            wr_byte(o_ptr.origin_depth);
            wr_u16b((ushort)o_ptr.origin_xtra);

            for (i = 0; i < Object.Object_Flag.BYTES && i < Object.Object_Flag.SIZE; i++)
            {
                wr_byte(o_ptr.flags[i]);
            }
            if (i < Object.Object_Flag.BYTES)
            {
                Savefile.pad_bytes(Object.Object_Flag.BYTES - i);
            }

            for (i = 0; i < Object.Object_Flag.BYTES && i < Object.Object_Flag.SIZE; i++)
            {
                wr_byte(o_ptr.known_flags[i]);
            }
            if (i < Object.Object_Flag.BYTES)
            {
                Savefile.pad_bytes(Object.Object_Flag.BYTES - i);
            }

            for (j = 0; j < Misc.MAX_PVALS; j++)
            {
                for (i = 0; i < Object.Object_Flag.BYTES && i < Object.Object_Flag.SIZE; i++)
                {
                    wr_byte(o_ptr.pval_flags[j][i]);
                }
                if (i < Object.Object_Flag.BYTES)
                {
                    Savefile.pad_bytes(Object.Object_Flag.BYTES - i);
                }
            }

            /* Held by monster index */
            wr_s16b(o_ptr.held_m_idx);

            wr_s16b(o_ptr.mimicking_m_idx);

            /* Save the inscription (if any) */
            if (o_ptr.note != null)
            {
                wr_string(o_ptr.note.ToString());
            }
            else
            {
                wr_string("");
            }
        }
示例#27
0
        /**
         * This is a helper function used by do_cmd_throw and do_cmd_fire.
         *
         * It abstracts out the projectile path, display code, identify and clean up
         * logic, while using the 'attack' parameter to do work particular to each
         * kind of attack.
         */
        public static void ranged_helper(int item, int dir, int range, int shots, ranged_attack attack)
        {
            /* Get the ammo */
            Object.Object o_ptr = Object.Object.object_from_item_idx(item);

            int          i, j;
            ConsoleColor missile_attr = o_ptr.object_attr();
            char         missile_char = o_ptr.object_char();

            //object_type object_type_body;
            Object.Object i_ptr = new Object.Object();            //&object_type_body;

            //char o_name[80];
            string o_name;

            int           path_n;
            List <ushort> path_g = new List <ushort>();          //[256];

            int msec = Player.Player_Other.instance.delay_factor;

            /* Start at the player */
            int x = Misc.p_ptr.px;
            int y = Misc.p_ptr.py;

            /* Predict the "target" location */
            short ty = (short)(y + 99 * Misc.ddy[dir]);
            short tx = (short)(x + 99 * Misc.ddx[dir]);

            bool hit_target = false;

            /* Check for target validity */
            if ((dir == 5) && Target.okay())
            {
                int taim;
                //char msg[80];
                string msg;
                Target.get(out tx, out ty);
                taim = Cave.distance(y, x, ty, tx);
                if (taim > range)
                {
                    msg = String.Format("Target out of range by {0} squares. Fire anyway? ", taim - range);
                    if (!Utilities.get_check(msg))
                    {
                        return;
                    }
                }
            }

            /* Sound */
            //sound(MSG_SHOOT); //later

            o_ptr.notice_on_firing();

            /* Describe the object */
            o_name = o_ptr.object_desc(Object.Object.Detail.FULL | Object.Object.Detail.SINGULAR);

            /* Actually "fire" the object -- Take a partial turn */
            Misc.p_ptr.energy_use = (short)(100 / shots);

            /* Calculate the path */
            path_n = Cave.project_path(out path_g, range, y, x, ty, tx, 0);

            /* Hack -- Handle stuff */
            Misc.p_ptr.handle_stuff();

            /* Start at the player */
            x = Misc.p_ptr.px;
            y = Misc.p_ptr.py;

            /* Project along the path */
            for (i = 0; i < path_n; ++i)
            {
                int ny = Cave.GRID_Y(path_g[i]);
                int nx = Cave.GRID_X(path_g[i]);

                /* Hack -- Stop before hitting walls */
                if (!Cave.cave_floor_bold(ny, nx))
                {
                    break;
                }

                /* Advance */
                x = nx;
                y = ny;

                /* Only do visuals if the player can "see" the missile */
                if (Cave.player_can_see_bold(y, x))
                {
                    Cave.print_rel(missile_char, missile_attr, y, x);
                    Cave.move_cursor_relative(y, x);

                    Term.fresh();
                    if (Misc.p_ptr.redraw != 0)
                    {
                        Misc.p_ptr.redraw_stuff();
                    }

                    Term.xtra(TERM_XTRA.DELAY, msec);
                    Cave.cave_light_spot(Cave.cave, y, x);

                    Term.fresh();
                    if (Misc.p_ptr.redraw != 0)
                    {
                        Misc.p_ptr.redraw_stuff();
                    }
                }
                else
                {
                    /* Delay anyway for consistency */
                    Term.xtra(TERM_XTRA.DELAY, msec);
                }

                /* Handle monster */
                if (Cave.cave.m_idx[y][x] > 0)
                {
                    break;
                }
            }

            /* Try the attack on the monster at (x, y) if any */
            if (Cave.cave.m_idx[y][x] > 0)
            {
                Monster.Monster m_ptr   = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]);
                Monster_Race    r_ptr   = Misc.r_info[m_ptr.r_idx];
                bool            visible = m_ptr.ml;

                bool fear = false;
                //char m_name[80];
                string m_name;
                string note_dies = r_ptr.monster_is_unusual() ? " is destroyed." : " dies.";

                attack_result result   = attack(o_ptr, y, x);
                int           dmg      = result.dmg;
                Message_Type  msg_type = result.msg_type;
                string        hit_verb = result.hit_verb;

                if (result.success)
                {
                    hit_target = true;

                    /* Get "the monster" or "it" */
                    m_name = m_ptr.monster_desc(0);

                    o_ptr.notice_attack_plusses();

                    /* No negative damage; change verb if no damage done */
                    if (dmg <= 0)
                    {
                        dmg      = 0;
                        hit_verb = "fail to harm";
                    }

                    if (!visible)
                    {
                        /* Invisible monster */
                        Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} finds a mark.", o_name);
                    }
                    else
                    {
                        /* Visible monster */
                        if ((Message_Type)msg_type == Message_Type.MSG_SHOOT_HIT)
                        {
                            Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} {1} {2}.", o_name, hit_verb, m_name);
                        }
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GOOD)
                        {
                            Utilities.msgt(Message_Type.MSG_HIT_GOOD, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                           "It was a good hit!");
                        }
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GREAT)
                        {
                            Utilities.msgt(Message_Type.MSG_HIT_GREAT, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                           "It was a great hit!");
                        }
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_SUPERB)
                        {
                            Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                           "It was a superb hit!");
                        }

                        /* Track this monster */
                        if (m_ptr.ml)
                        {
                            Cave.monster_race_track(m_ptr.r_idx);
                        }
                        if (m_ptr.ml)
                        {
                            Cave.health_track(Misc.p_ptr, Cave.cave.m_idx[y][x]);
                        }
                    }

                    /* Complex message */
                    if (Misc.p_ptr.wizard)
                    {
                        Utilities.msg("You do {0} (out of {1}) damage.", dmg, m_ptr.hp);
                    }

                    /* Hit the monster, check for death */
                    if (!Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, note_dies))
                    {
                        Monster_Message.message_pain(Cave.cave.m_idx[y][x], dmg);
                        if (fear && m_ptr.ml)
                        {
                            Monster_Message.add_monster_message(m_name, Cave.cave.m_idx[y][x], MON_MSG.FLEE_IN_TERROR, true);
                        }
                    }
                }
            }

            /* Obtain a local object */
            i_ptr = o_ptr.copy();
            i_ptr.split(o_ptr, 1);

            /* See if the ammunition broke or not */
            j = i_ptr.breakage_chance(hit_target);

            /* Drop (or break) near that location */
            Object.Object.drop_near(Cave.cave, i_ptr, j, y, x, true);

            if (item >= 0)
            {
                /* The ammo is from the inventory */
                Object.Object.inven_item_increase(item, -1);
                Object.Object.inven_item_describe(item);
                Object.Object.inven_item_optimize(item);
            }
            else
            {
                /* The ammo is from the floor */
                Object.Object.floor_item_increase(0 - item, -1);
                Object.Object.floor_item_optimize(0 - item);
            }
        }
示例#28
0
        /*
         * Remove a slot if it is empty, in store 'st'.
         */
        public void item_optimize(int item)
        {
            int j;
            Object.Object o_ptr;

            /* Get the object */
            o_ptr = stock[item];

            /* Must exist */
            if (o_ptr.kind == null) return;

            /* Must have no items */
            if (o_ptr.number != 0) return;

            /* One less object */
            stock_num--;

            /* Slide everyone */
            for (j = item; j < stock_num; j++)
            {
                stock[j] = stock[j + 1];
            }

            /* Nuke the final slot */
            stock[j] = new Object.Object();
            //object_wipe(&store.stock[j]);
        }
示例#29
0
        /*
         * Identify an item.
         *
         * `item` is used to print the slot occupied by an object in equip/inven.
         * Any negative value assigned to "item" can be used for specifying an object
         * on the floor.
         */
        public static void do_ident_item(int item, Object.Object o_ptr)
        {
            string o_name = "";            //80

            Message_Type msg_type = (Message_Type)0;
            int          i;
            bool         bad = true;

            /* Identify it */
            o_ptr.flavor_aware();
            o_ptr.notice_everything();

            /* Apply an autoinscription, if necessary */
            Squelch.apply_autoinscription(o_ptr);

            /* Set squelch flag */
            Misc.p_ptr.notice |= (int)Misc.PN_SQUELCH;

            /* Recalculate bonuses */
            Misc.p_ptr.update |= (Misc.PU_BONUS);

            /* Combine / Reorder the pack (later) */
            Misc.p_ptr.notice |= (int)(Misc.PN_COMBINE | Misc.PN_REORDER | Misc.PN_SORT_QUIVER);

            /* Window stuff */
            Misc.p_ptr.redraw |= (Misc.PR_INVEN | Misc.PR_EQUIP);

            /* Description */
            o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);

            /* Determine the message type. */

            /* CC: we need to think more carefully about how we define "bad" with
             * multiple pvals - currently using "all nonzero pvals < 0" */
            for (i = 0; i < o_ptr.num_pvals; i++)
            {
                if (o_ptr.pval[i] > 0)
                {
                    bad = false;
                }
            }

            if (bad)
            {
                msg_type = Message_Type.MSG_IDENT_BAD;
            }
            else if (o_ptr.artifact != null)
            {
                msg_type = Message_Type.MSG_IDENT_ART;
            }
            else if (o_ptr.ego != null)
            {
                msg_type = Message_Type.MSG_IDENT_EGO;
            }
            else
            {
                msg_type = Message_Type.MSG_GENERIC;
            }

            /* Log artifacts to the history list. */
            if (o_ptr.artifact != null)
            {
                History.add_artifact(o_ptr.artifact, true, true);
            }

            /* Describe */
            if (item >= Misc.INVEN_WIELD)
            {
                Utilities.msgt(msg_type, "{0}: {1} ({2}).", Object.Object.describe_use(item), o_name, Object.Object.index_to_label(item));
                //Utilities.msgt(msg_type, "%^s: %s (%c).", describe_use(item), o_name, index_to_label(item));
            }
            else if (item >= 0)
            {
                Utilities.msgt(msg_type, "In your pack: {0} ({1}).", o_name, Object.Object.index_to_label(item));
                //Utilities.msgt(msg_type, "In your pack: %s (%c).", o_name, index_to_label(item));
            }
            else
            {
                Utilities.msgt(msg_type, "On the ground: {0}.", o_name);
            }
        }
示例#30
0
        /**
         * Place a random amount of gold at (x, y).
         */
        public static void place_gold(Cave c, int y, int x, int level, Origin origin)
        {
            Object.Object i_ptr;
            //object_type object_type_body;

            Misc.assert(cave_in_bounds(c, y, x));

            if (!cave_canputitem(c, y, x)) return;

            //i_ptr = &object_type_body;
            //object_wipe(i_ptr);
            i_ptr = new Object.Object();
            Object.Object.make_gold(ref i_ptr, level, (int)SVal.sval_gold.SV_GOLD_ANY);

            i_ptr.origin = origin;
            i_ptr.origin_depth = (byte)level;

            Object.Object.floor_carry(c, y, x, i_ptr);
        }
示例#31
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);
        }
示例#32
0
        /*
         * Determine the squelch level of an object, which is similar to its pseudo.
         *
         * The main point is when the value is undetermined given current info,
         * return the maximum possible value.
         */
        public static quality_squelch squelch_level_of(Object.Object o_ptr)
        {
            quality_squelch value = quality_squelch.SQUELCH_NONE;
            Bitflag         f     = new Bitflag(Object_Flag.SIZE);
            Bitflag         f2    = new Bitflag(Object_Flag.SIZE);
            int             i;

            o_ptr.object_flags_known(ref f);

            /* Deal with jewelry specially. */
            if (o_ptr.is_jewelry())
            {
                /* CC: average jewelry has at least one known positive pval */
                for (i = 0; i < o_ptr.num_pvals; i++)
                {
                    if ((o_ptr.this_pval_is_visible(i)) && (o_ptr.pval[i] > 0))
                    {
                        return(quality_squelch.SQUELCH_AVERAGE);
                    }
                }

                if ((o_ptr.to_h > 0) || (o_ptr.to_d > 0) || (o_ptr.to_a > 0))
                {
                    return(quality_squelch.SQUELCH_AVERAGE);
                }
                if ((o_ptr.attack_plusses_are_visible() &&
                     ((o_ptr.to_h < 0) || (o_ptr.to_d < 0))) ||
                    (o_ptr.defence_plusses_are_visible() && o_ptr.to_a < 0))
                {
                    return(quality_squelch.SQUELCH_BAD);
                }

                return(quality_squelch.SQUELCH_AVERAGE);
            }

            /* And lights */
            if (o_ptr.tval == TVal.TV_LIGHT)
            {
                Object_Flag.create_mask(f2, true, Object_Flag.object_flag_id.WIELD);
                if (f.is_inter(f2))
                {
                    return(quality_squelch.SQUELCH_ALL);
                }
                if ((o_ptr.to_h > 0) || (o_ptr.to_d > 0) || (o_ptr.to_a > 0))
                {
                    return(quality_squelch.SQUELCH_GOOD);
                }
                if ((o_ptr.to_h < 0) || (o_ptr.to_d < 0) || (o_ptr.to_a < 0))
                {
                    return(quality_squelch.SQUELCH_BAD);
                }

                return(quality_squelch.SQUELCH_AVERAGE);
            }

            /* CC: we need to redefine "bad" with multiple pvals
             * At the moment we use "all pvals known and negative" */
            for (i = 0; i < o_ptr.num_pvals; i++)
            {
                if (!o_ptr.this_pval_is_visible(i) ||
                    (o_ptr.pval[i] > 0))
                {
                    break;
                }

                if (i == (o_ptr.num_pvals - 1))
                {
                    return(quality_squelch.SQUELCH_BAD);
                }
            }

            if (o_ptr.was_sensed())
            {
                Object.Object.obj_pseudo_t pseudo = o_ptr.pseudo();

                switch (pseudo)
                {
                case Object.Object.obj_pseudo_t.INSCRIP_AVERAGE: {
                    value = quality_squelch.SQUELCH_AVERAGE;
                    break;
                }

                case Object.Object.obj_pseudo_t.INSCRIP_EXCELLENT: {
                    /* have to assume splendid until you have tested it */
                    if (o_ptr.was_worn())
                    {
                        if (o_ptr.high_resist_is_possible())
                        {
                            value = quality_squelch.SQUELCH_EXCELLENT_NO_SPL;
                        }
                        else
                        {
                            value = quality_squelch.SQUELCH_EXCELLENT_NO_HI;
                        }
                    }
                    else
                    {
                        value = quality_squelch.SQUELCH_ALL;
                    }
                    break;
                }

                case Object.Object.obj_pseudo_t.INSCRIP_SPLENDID:
                    value = quality_squelch.SQUELCH_ALL;
                    break;

                case Object.Object.obj_pseudo_t.INSCRIP_null:
                case Object.Object.obj_pseudo_t.INSCRIP_SPECIAL:
                    value = quality_squelch.SQUELCH_MAX;
                    break;

                /* This is the interesting case */
                case Object.Object.obj_pseudo_t.INSCRIP_STRANGE:
                case Object.Object.obj_pseudo_t.INSCRIP_MAGICAL: {
                    value = quality_squelch.SQUELCH_GOOD;

                    if ((o_ptr.attack_plusses_are_visible() ||
                         Random.randcalc_valid(o_ptr.kind.to_h, o_ptr.to_h) ||
                         Random.randcalc_valid(o_ptr.kind.to_d, o_ptr.to_d)) &&
                        (o_ptr.defence_plusses_are_visible() ||
                         Random.randcalc_valid(o_ptr.kind.to_a, o_ptr.to_a)))
                    {
                        int isgood = is_object_good(o_ptr);
                        if (isgood > 0)
                        {
                            value = quality_squelch.SQUELCH_GOOD;
                        }
                        else if (isgood < 0)
                        {
                            value = quality_squelch.SQUELCH_BAD;
                        }
                        else
                        {
                            value = quality_squelch.SQUELCH_AVERAGE;
                        }
                    }
                    break;
                }

                default:
                    /* do not handle any other possible pseudo values */
                    Misc.assert(false);
                    break;
                }
            }
            else
            {
                if (o_ptr.was_worn())
                {
                    value = quality_squelch.SQUELCH_EXCELLENT_NO_SPL;             /* object would be sensed if it were splendid */
                }
                else if (o_ptr.is_known_not_artifact())
                {
                    value = quality_squelch.SQUELCH_ALL;
                }
                else
                {
                    value = quality_squelch.SQUELCH_MAX;
                }
            }

            return(value);
        }
示例#33
0
        /**
         * Try to wield everything wieldable in the inventory.
         */
        static void wield_all(Player.Player p)
        {
            Object.Object o_ptr;
            Object.Object i_ptr;
            //Object.Object object_type_body;

            int  slot;
            int  item;
            int  num;
            bool is_ammo;

            /* Scan through the slots backwards */
            for (item = Misc.INVEN_PACK - 1; item >= 0; item--)
            {
                o_ptr   = p.inventory[item];
                is_ammo = o_ptr.is_ammo();

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

                /* Make sure we can wield it */
                slot = o_ptr.wield_slot();
                if (slot < Misc.INVEN_WIELD)
                {
                    continue;
                }

                i_ptr = p.inventory[slot];
                if (i_ptr.kind != null && (!is_ammo || (is_ammo && !o_ptr.similar(i_ptr, Object.Object.object_stack_t.OSTACK_PACK))))
                {
                    continue;
                }

                /* Figure out how much of the item we'll be wielding */
                num = is_ammo ? o_ptr.number : 1;

                /* Get local object */
                i_ptr = new Object.Object();
                i_ptr = o_ptr.copy();
                //This entire bit was uber shadey... Rewrote above
                ////i_ptr = object_type_body;
                //p.inventory[slot] = o_ptr; //object_copy(i_ptr, o_ptr); //This might not work...
                //i_ptr = o_ptr;  //If wonky equips happen, check here

                /* Modify quantity */
                i_ptr.number = (byte)num;

                /* Decrease the item (from the pack) */
                Object.Object.inven_item_increase(item, -num);
                Object.Object.inven_item_optimize(item);

                /* Get the wield slot */
                //o_ptr = p.inventory[slot];

                /* Wear the new stuff */
                //object_copy(o_ptr, i_ptr);
                p.inventory[slot] = i_ptr;

                /* Increase the weight */
                p.total_weight += i_ptr.weight * i_ptr.number;

                /* Increment the equip counter by hand */
                p.equip_cnt++;
            }

            Object.Object.save_quiver_size(p);

            return;
        }
示例#34
0
        /**
         * Attack the monster at the given location with a single blow.
         */
        static bool py_attack_real(int y, int x, ref bool fear)
        {
            /* Information about the target of the attack */
            Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]);
            Monster_Race    r_ptr = Misc.r_info[m_ptr.r_idx];
            //char m_name[80];
            string m_name;
            bool   stop = false;

            /* The weapon used */
            Object.Object o_ptr = Misc.p_ptr.inventory[Misc.INVEN_WIELD];

            /* Information about the attack */
            int  bonus    = Misc.p_ptr.state.to_h + o_ptr.to_h;
            int  chance   = Misc.p_ptr.state.skills[(int)Skill.TO_HIT_MELEE] + bonus * Misc.BTH_PLUS_ADJ;
            bool do_quake = false;
            bool success  = false;

            /* Default to punching for one damage */
            string       hit_verb = "punch";
            int          dmg      = 1;
            Message_Type msg_type = Message_Type.MSG_HIT;

            /* Extract monster name (or "it") */
            m_name = m_ptr.monster_desc(0);

            /* Auto-Recall if possible and visible */
            if (m_ptr.ml)
            {
                Cave.monster_race_track(m_ptr.r_idx);
            }

            /* Track a new monster */
            if (m_ptr.ml)
            {
                Cave.health_track(Misc.p_ptr, Cave.cave.m_idx[y][x]);
            }

            /* Handle player fear (only for invisible monsters) */
            if (Misc.p_ptr.check_state(Object_Flag.AFRAID, Misc.p_ptr.state.flags))
            {
                Utilities.msgt(Message_Type.MSG_AFRAID, "You are too afraid to attack {0}!", m_name);
                return(false);
            }

            /* Disturb the monster */
            Monster.Monster.mon_clear_timed(Cave.cave.m_idx[y][x], (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOMESSAGE, false);

            /* See if the player hit */
            success = test_hit(chance, (int)r_ptr.ac, m_ptr.ml);

            /* If a miss, skip this hit */
            if (!success)
            {
                Utilities.msgt(Message_Type.MSG_MISS, "You miss {0}.", m_name);
                return(false);
            }

            /* Handle normal weapon */
            if (o_ptr.kind != null)
            {
                int  i;
                Slay best_s_ptr = null;

                hit_verb = "hit";

                /* Get the best attack from all slays or
                 * brands on all non-launcher equipment */
                for (i = Misc.INVEN_LEFT; i < Misc.INVEN_TOTAL; i++)
                {
                    Object.Object obj = Misc.p_ptr.inventory[i];
                    if (obj.kind != null)
                    {
                        Slay.improve_attack_modifier(obj, m_ptr, ref best_s_ptr, true, false);
                    }
                }

                Slay.improve_attack_modifier(o_ptr, m_ptr, ref best_s_ptr, true, false);
                if (best_s_ptr != null)
                {
                    hit_verb = best_s_ptr.melee_verb;
                }

                dmg  = Random.damroll(o_ptr.dd, o_ptr.ds);
                dmg *= (best_s_ptr == null) ? 1 : best_s_ptr.mult;

                dmg += o_ptr.to_d;
                dmg  = critical_norm(o_ptr.weight, o_ptr.to_h, dmg, ref msg_type);

                /* Learn by use for the weapon */
                o_ptr.notice_attack_plusses();

                if (Misc.p_ptr.check_state(Object_Flag.IMPACT, Misc.p_ptr.state.flags) && dmg > 50)
                {
                    do_quake = true;
                    Object.Object.wieldeds_notice_flag(Misc.p_ptr, Object_Flag.IMPACT.value);
                }
            }

            /* Learn by use for other equipped items */
            Object.Object.wieldeds_notice_on_attack();

            /* Apply the player damage bonuses */
            dmg += Misc.p_ptr.state.to_d;

            /* No negative damage */
            if (dmg <= 0)
            {
                dmg = 0;
            }

            /* Tell the player what happened */
            if (dmg <= 0)
            {
                Utilities.msgt(Message_Type.MSG_MISS, "You fail to harm {0}.", m_name);
            }
            else if (msg_type == Message_Type.MSG_HIT)
            {
                Utilities.msgt(Message_Type.MSG_HIT, "You {0} {1}.", hit_verb, m_name);
            }
            else if (msg_type == Message_Type.MSG_HIT_GOOD)
            {
                Utilities.msgt(Message_Type.MSG_HIT_GOOD, "You {0} {1}. {2}", hit_verb, m_name, "It was a good hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_GREAT)
            {
                Utilities.msgt(Message_Type.MSG_HIT_GREAT, "You {0} {1}. {2}", hit_verb, m_name, "It was a great hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_SUPERB)
            {
                Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "You {0} {1}. {2}", hit_verb, m_name, "It was a superb hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_HI_GREAT)
            {
                Utilities.msgt(Message_Type.MSG_HIT_HI_GREAT, "You {0} {1}. {2}", hit_verb, m_name, "It was a *GREAT* hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_HI_SUPERB)
            {
                Utilities.msgt(Message_Type.MSG_HIT_HI_SUPERB, "You {0} {1}. {2}", hit_verb, m_name, "It was a *SUPERB* hit!");
            }

            /* Complex message */
            if (Misc.p_ptr.wizard)
            {
                Utilities.msg("You do {0} (out of {1}) damage.", dmg, m_ptr.hp);
            }

            /* Confusion attack */
            if (Misc.p_ptr.confusing != 0)
            {
                Misc.p_ptr.confusing = 0;                //false;
                Utilities.msg("Your hands stop glowing.");

                Monster.Monster.mon_inc_timed(Cave.cave.m_idx[y][x], Misc.MON_TMD.CONF,
                                              (10 + Random.randint0(Misc.p_ptr.lev) / 10), Misc.MON_TMD_FLG_NOTIFY, false);
            }

            /* Damage, check for fear and death */
            stop = Monster.Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, null);

            if (stop)
            {
                fear = false;
            }

            /* Apply earthquake brand */
            if (do_quake)
            {
                throw new NotImplementedException();
                //earthquake(Misc.p_ptr.py, Misc.p_ptr.px, 10);
                //if (Cave.cave.m_idx[y][x] == 0) stop = true;
            }

            return(stop);
        }
示例#35
0
        /*
         * Buy the item with the given index from the current store's inventory.
         */
        public static void buy(Command_Code code, cmd_arg[] args)
        {
            int item = args[0].value;
            int amt = args[1].value;

            Object.Object o_ptr;
            //object_type object_type_body;
            Object.Object i_ptr = new Object.Object();//&object_type_body;

            //char o_name[80];
            string o_name;
            int price, item_new;

            Store store = Store.current_store();

            if (store == null) {
                Utilities.msg("You cannot purchase items when not in a store.");
                return;
            }

            /* Get the actual object */
            o_ptr = store.stock[item];

            /* Get desired object */
            Object.Object.copy_amt(ref i_ptr, o_ptr, amt);

            /* Ensure we have room */
            if (!i_ptr.inven_carry_okay())
            {
                Utilities.msg("You cannot carry that many items.");
                return;
            }

            /* Describe the object (fully) */
            o_name = i_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);

            /* Extract the price for the entire stack */
            price = Store.price_item(i_ptr, false, i_ptr.number);

            if (price > Misc.p_ptr.au)
            {
                Utilities.msg("You cannot afford that purchase.");
                return;
            }

            /* Spend the money */
            Misc.p_ptr.au -= price;

            /* Update the display */
            Store.store_flags |= Store.STORE_GOLD_CHANGE;

            /* ID objects on buy */
            i_ptr.notice_everything();

            /* Combine / Reorder the pack (later) */
            Misc.p_ptr.notice |= (Misc.PN_COMBINE | Misc.PN_REORDER | Misc.PN_SORT_QUIVER | Misc.PN_SQUELCH);

            /* The object no longer belongs to the store */
            i_ptr.ident &= ~(Object.Object.IDENT_STORE);

            /* Message */
            if (Random.one_in_(3)) Utilities.msgt(Message_Type.MSG_STORE5, "{0}", Store.comment_accept[Random.randint0(Store.comment_accept.Length)]);
            Utilities.msg("You bought {0} for {1} gold.", o_name, (long)price);

            /* Erase the inscription */
            i_ptr.note = null;

            /* Give it to the player */
            item_new = i_ptr.inven_carry(Misc.p_ptr);

            /* Message */
            o_name = Misc.p_ptr.inventory[item_new].object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);
            Utilities.msg("You have {0} ({1}).", o_name, Object.Object.index_to_label(item_new));

            /* Hack - Reduce the number of charges in the original stack */
            if (o_ptr.tval == TVal.TV_WAND || o_ptr.tval == TVal.TV_STAFF)
            {
                o_ptr.pval[Misc.DEFAULT_PVAL] -= i_ptr.pval[Misc.DEFAULT_PVAL];
            }

            /* Handle stuff */
            Misc.p_ptr.handle_stuff();

            /* Remove the bought objects from the store */

            store.item_increase(item, -amt);
            store.item_optimize(item);

            /* Store is empty */
            if (store.stock_num == 0)
            {
                int i;

                /* Shuffle */
                if (Random.one_in_(Store.SHUFFLE))
                {
                    /* Message */
                    Utilities.msg("The shopkeeper retires.");

                    /* Shuffle the store */
                    store.store_shuffle();
                    Store.store_flags |= Store.STORE_FRAME_CHANGE;
                }

                /* Maintain */
                else
                {
                    /* Message */
                    Utilities.msg("The shopkeeper brings out some new stock.");
                }

                /* New inventory */
                for (i = 0; i < 10; ++i)
                    store.store_maint();
            }

            Game_Event.signal(Game_Event.Event_Type.INVENTORY);
            Game_Event.signal(Game_Event.Event_Type.EQUIPMENT);
        }