예제 #1
0
        /*
         * Get the next game command, with 'wait' indicating whether we
         * are prepared to wait for a command or require a quick return with
         * no command.
         */
        public static Game_Command get(cmd_context c, ref Game_Command cmd, bool wait)
        {
            /* If we're repeating, just pull the last command again. */
            if (repeating)
            {
                cmd = cmd_queue[prev_cmd_idx(cmd_tail)];
                return(cmd);
            }

            /* If there are no commands queued, ask the UI for one. */
            if (cmd_head == cmd_tail)
            {
                cmd_get_hook(c, wait);
            }

            /* If we have a command ready, set it and return success. */
            if (cmd_head != cmd_tail)
            {
                cmd = cmd_queue[cmd_tail++];
                if (cmd_tail == CMD_QUEUE_SIZE)
                {
                    cmd_tail = 0;
                }

                return(cmd);
            }

            /* Failure to get a command. */
            return(null);
        }
예제 #2
0
        public static void cmd_rest()
        {
            /* Prompt for time if needed */
            if (Misc.p_ptr.command_arg <= 0)
            {
                string p = "Rest (0-9999, '!' for HP or SP, '*' for HP and SP, '&' as needed): ";

                string out_val = "& ";
                //char out_val[5] = "& ";

                /* Ask for duration */
                if (!Utilities.get_string(p, ref out_val, 4))
                {
                    return;
                }

                /* Rest until done */
                if (out_val[0] == '&')
                {
                    Game_Command.insert(Command_Code.REST);
                    Game_Command.get_top().set_arg_choice(0, (int)Misc.REST.COMPLETE);
                }

                /* Rest a lot */
                else if (out_val[0] == '*')
                {
                    Game_Command.insert(Command_Code.REST);
                    Game_Command.get_top().set_arg_choice(0, (int)Misc.REST.ALL_POINTS);
                }

                /* Rest until HP or SP filled */
                else if (out_val[0] == '!')
                {
                    Game_Command.insert(Command_Code.REST);
                    Game_Command.get_top().set_arg_choice(0, (int)Misc.REST.SOME_POINTS);
                }

                /* Rest some */
                else
                {
                    int turns = int.Parse(out_val);
                    if (turns <= 0)
                    {
                        return;
                    }
                    if (turns > 9999)
                    {
                        turns = 9999;
                    }

                    Game_Command.insert(Command_Code.REST);
                    Game_Command.get_top().set_arg_choice(0, (int)turns);
                }
            }
        }
예제 #3
0
        /*
         * Hack -- main Angband initialization entry point
         *
         * Verify some files, display the "news.txt" file, create
         * the high score file, initialize all internal arrays, and
         * load the basic "user pref files".
         *
         * Be very careful to keep track of the order in which things
         * are initialized, in particular, the only thing *known* to
         * be available when this function is called is the "z-term.c"
         * package, and that may not be fully initialized until the
         * end of this function, when the default "user pref files"
         * are loaded and "Term_xtra(TERM_XTRA_REACT,0)" is called.
         *
         * Note that this function attempts to verify the "news" file,
         * and the game aborts (cleanly) on failure, since without the
         * "news" file, it is likely that the "lib" folder has not been
         * correctly located.  Otherwise, the news file is displayed for
         * the user.
         *
         * Note that this function attempts to verify (or create) the
         * "high score" file, and the game aborts (cleanly) on failure,
         * since one of the most common "extraction" failures involves
         * failing to extract all sub-directories (even empty ones), such
         * as by failing to use the "-d" option of "pkunzip", or failing
         * to use the "save empty directories" option with "Compact Pro".
         * This error will often be caught by the "high score" creation
         * code below, since the "lib/apex" directory, being empty in the
         * standard distributions, is most likely to be "lost", making it
         * impossible to create the high score file.
         *
         * Note that various things are initialized by this function,
         * including everything that was once done by "init_some_arrays".
         *
         * This initialization involves the parsing of special files
         * in the "lib/edit" directories.
         *
         * Note that the "template" files are initialized first, since they
         * often contain errors.  This means that macros and message recall
         * and things like that are not available until after they are done.
         *
         * We load the default "user pref files" here in case any "color"
         * changes are needed before character creation.
         *
         * Note that the "graf-xxx.prf" file must be loaded separately,
         * if needed, in the first (?) pass through "TERM_XTRA_REACT".
         */
        public static bool init_angband()
        {
            Game_Event.signal(Game_Event.Event_Type.ENTER_INIT);

            /*** Initialize some arrays ***/
            Init.arrays();

            /*** Load default user pref files ***/

            /* Initialize feature info */
            Game_Event.signal_string(Game_Event.Event_Type.INITSTATUS, "Loading basic user pref file...");

            /* Process that file */
            Prefs.process_pref_file("pref.prf", false, false);

            /* Done */
            Game_Event.signal_string(Game_Event.Event_Type.INITSTATUS, "Initialization complete");

            /* Sneakily init command list */
            Command.Init();

            //#ifdef ALLOW_BORG /* apw */
            //    /* Allow the screensaver to do its work  */
            //    if (screensaver)
            //    {
            //        event_signal(EVENT_LEAVE_INIT);
            //        return !file_exists(savefile);
            //    }
            //#endif /* ALLOW_BORG */

            /* Ask for a "command" until we get one we like. */
            while (true)
            {
                Game_Command command_req = new Game_Command();

                if (Game_Command.get(cmd_context.CMD_INIT, ref command_req, true) == null)
                {
                    continue;
                }
                else if (command_req.command == Command_Code.QUAFF)
                {
                    Utilities.quit();
                }
                else if (command_req.command == Command_Code.NEWGAME)
                {
                    Game_Event.signal(Game_Event.Event_Type.LEAVE_INIT);
                    return(true);
                }
                else if (command_req.command == Command_Code.LOADFILE)
                {
                    Game_Event.signal(Game_Event.Event_Type.LEAVE_INIT);
                    return(false);
                }
            }
        }
예제 #4
0
        /* ------------------------------------------------------------------------
         * Final confirmation of character.
         * ------------------------------------------------------------------------ */
        static birth_stage get_confirm_command()
        {
            Player.Player p_ptr = Player.Player.instance;

            string   prompt = "['ESC' to step back, 'S' to start over, or any other key to continue]";
            keypress ke;

            birth_stage next;

            /* Prompt for it */
            Utilities.prt(prompt, Term.instance.hgt - 1, Term.instance.wid / 2 - (prompt.Length / 2));

            /* Buttons */
            Button.button_kill_all();
            Button.button_add("[Continue]", 'q');
            Button.button_add("[ESC]", (char)keycode_t.ESCAPE);
            Button.button_add("[S]", 'S');
            p_ptr.redraw_stuff();

            /* Get a key */
            ke = Utilities.inkey();

            /* Start over */
            if (ke.code == (keycode_t)'S' || ke.code == (keycode_t)'s')
            {
                next = birth_stage.BIRTH_RESET;
            }
            else if (ke.code == (keycode_t)UIEvent.KTRL('X'))
            {
                Game_Command.insert(Command_Code.QUIT);
                next = birth_stage.BIRTH_COMPLETE;
            }
            else if (ke.code == keycode_t.ESCAPE)
            {
                next = birth_stage.BIRTH_BACK;
            }
            else
            {
                Game_Command.insert(Command_Code.ACCEPT_CHARACTER);
                next = birth_stage.BIRTH_COMPLETE;
            }

            /* Buttons */
            Button.button_kill_all();
            p_ptr.redraw_stuff();

            /* Clear prompt */
            Utilities.clear_from(23);

            return(next);
        }
예제 #5
0
        /*
         * Inserts a command in the queue to be carried out, with the given
         * number of repeats.
         */
        public static int insert_repeated(Command_Code c, int nrepeats)
        {
            Game_Command cmd = new Game_Command();

            if (cmd_idx(c) == -1)
            {
                return(1);
            }

            cmd.command  = c;
            cmd.nrepeats = nrepeats;

            return(cmd_insert_s(ref cmd));
        }
예제 #6
0
        /*
         * Remove any pending repeats from the current command.
         */
        public static void cancel_repeat()
        {
            Game_Command cmd = cmd_queue[prev_cmd_idx(cmd_tail)];

            if (cmd.nrepeats != 0 || repeating)
            {
                /* Cancel */
                cmd.nrepeats = 0;
                repeating    = false;

                /* Redraw the state (later) */
                Misc.p_ptr.redraw |= (Misc.PR_STATE);
            }
        }
예제 #7
0
        /*
         * Insert the given command into the command queue.
         */
        static int cmd_insert_s(ref Game_Command cmd)
        {
            /* If queue full, return error */
            if (cmd_head + 1 == cmd_tail)
            {
                return(1);
            }
            if (cmd_head + 1 == CMD_QUEUE_SIZE && cmd_tail == 0)
            {
                return(1);
            }

            /* Insert command into queue. */
            if (cmd.command != Command_Code.REPEAT)
            {
                cmd_queue[cmd_head] = cmd;
            }
            else
            {
                int cmd_prev = cmd_head - 1;

                //was previously just "repeat_prev_allowed"
                if (!repeat_prev_allowed)
                {
                    return(1);
                }

                /* If we're repeating a command, we duplicate the previous command
                 * in the next command "slot". */
                if (cmd_prev < 0)
                {
                    cmd_prev = CMD_QUEUE_SIZE - 1;
                }

                if (cmd_queue[cmd_prev].command != Command_Code.NULL)
                {
                    cmd_queue[cmd_head] = cmd_queue[cmd_prev];
                }
            }

            /* Advance point in queue, wrapping around at the end */
            cmd_head++;
            if (cmd_head == CMD_QUEUE_SIZE)
            {
                cmd_head = 0;
            }

            return(0);
        }
예제 #8
0
        /*
         * Update the number of repeats pending for the current command.
         */
        public static void set_repeat(int nrepeats)
        {
            Game_Command cmd = cmd_queue[prev_cmd_idx(cmd_tail)];

            cmd.nrepeats = nrepeats;
            if (nrepeats != 0)
            {
                repeating = true;
            }
            else
            {
                repeating = false;
            }

            /* Redraw the state (later) */
            Misc.p_ptr.redraw |= (Misc.PR_STATE);
        }
예제 #9
0
        /* ------------------------------------------------------------------------
         * Asking for the player's chosen name.
         * ------------------------------------------------------------------------ */
        static birth_stage get_name_command()
        {
            birth_stage next;
            string      name = "";

            if (Utilities.get_name(ref name, 32))
            {
                Game_Command.insert(Command_Code.NAME_CHOICE);
                Game_Command.get_top().set_arg_choice(0, name);
                next = birth_stage.BIRTH_FINAL_CONFIRM;
            }
            else
            {
                next = birth_stage.BIRTH_BACK;
            }

            return(next);
        }
예제 #10
0
        /*
         * Pass the appropriate "Initialisation screen" command to the game,
         * getting user input if needed.
         */
        static int get_init_cmd()
        {
            /* Wait for response */
            Utilities.pause_line(Term.instance);

            if (new_game)
            {
                Game_Command.insert(Command_Code.NEWGAME);
            }
            else
            {
                /* This might be modified to supply the filename in future. */
                Game_Command.insert(Command_Code.LOADFILE);
            }

            /* Everything's OK. */
            return(0);
        }
예제 #11
0
        /**
         * Process a textui keypress.
         */
        static bool process_key(keypress kp)
        {
            Command_Info cmd;

            /* XXXmacro this needs rewriting */
            char c = (char)kp.code;

            if (c == '\n' || c == '\r')
            {
                c = TextUI.action_menu_choose();
            }

            if (c == '\0' || c == (char)keycode_t.ESCAPE || c == ' ' || c == '\a')
            {
                return(true);
            }

            cmd = Command.converted_list[c];
            if (cmd == null)
            {
                return(false);
            }

            if (Command.key_confirm_command(c) && (cmd.prereq == null || cmd.prereq()))
            {
                if (cmd.hook != null)
                {
                    cmd.hook();
                }
                else if (cmd.cmd != Command_Code.NULL)
                {
                    Game_Command.insert_repeated(cmd.cmd, Misc.p_ptr.command_arg);
                }
            }

            return(true);
        }
예제 #12
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);
            }
        }
예제 #13
0
        /*
         * Create a new character.
         *
         * Note that we may be called with "junk" leftover in the various
         * fields, so we must be sure to clear them first.
         */
        public static void player_birth(bool quickstart_allowed)
        {
            Game_Command blank = new Game_Command(Command_Code.NULL, null, null, false, 0);
            Game_Command cmd = blank;

            short[] stats = new short[(int)Stat.Max];
            int[] points_spent = new int[(int)Stat.Max];
            int points_left = 0;
            string buf;
            int success;

            bool rolled_stats = false;

            /*
             * The last character displayed, to allow the user to flick between two.
             * We rely on prev.age being zero to determine whether there is a stored
             * character or not, so initialise it here.
             */
            Birther prev = new Birther();

            /*
             * If quickstart is allowed, we store the old character in this,
             * to allow for it to be reloaded if we step back that far in the
             * birth process.
             */
            Birther quickstart_prev = new Birther();

            /*
             * If there's a quickstart character, store it for later use.
             * If not, default to whatever the first of the choices is.
             */
            if(quickstart_allowed) {
                quickstart_prev.save_roller_data();
            } else {
                Player.Player.instance.psex = 0;
                /* XXX default race/class */
                Player.Player.instance.Class = Misc.classes;
                Player.Player.instance.Race = Misc.races;
                Player.Player.instance.generate(null, null, null);
            }

            /* Handle incrementing name suffix */
            buf = Utilities.find_roman_suffix_start(Player_Other.instance.full_name);

            if (buf != null)
            {
                /* Try to increment the roman suffix */
                success = Utilities.int_to_roman((Utilities.roman_to_int(buf) + 1), buf);

                if (success == 0) Utilities.msg("Sorry, could not deal with suffix");
            }

            /* We're ready to start the interactive birth process. */
            Game_Event.signal_flag(Game_Event.Event_Type.ENTER_BIRTH, quickstart_allowed);

            /*
             * Loop around until the UI tells us we have an acceptable character.
             * Note that it is possible to quit from inside this loop.
             */
            while (cmd.command != Command_Code.ACCEPT_CHARACTER)
            {
                /* Grab a command from the queue - we're happy to wait for it. */
                if (Game_Command.get(cmd_context.CMD_BIRTH, ref cmd, true) == null) continue;

                if (cmd.command == Command_Code.BIRTH_RESET)
                {
                    Player.Player.instance.generate(null, null, null);
                    reset_stats(stats, points_spent, ref points_left);
                    do_birth_reset(quickstart_allowed, quickstart_prev);
                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.CHOOSE_SEX)
                {
                    Player.Player.instance.psex = (byte)cmd.arg[0].value;
                    Player.Player.instance.generate(null, null, null);
                }
                else if (cmd.command == Command_Code.CHOOSE_RACE)
                {
                    Player.Player.instance.generate(null, Player_Race.player_id2race(cmd.arg[0].value), null);

                    reset_stats(stats, points_spent, ref points_left);
                    generate_stats(stats, points_spent, ref points_left);
                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.CHOOSE_CLASS)
                {
                    Player.Player.instance.generate(null, null, Player_Class.player_id2class(cmd.arg[0].value));

                    reset_stats(stats, points_spent, ref points_left);
                    generate_stats(stats, points_spent, ref points_left);
                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.FINALIZE_OPTIONS)
                {
                    /* Reset score options from cheat options */
                    for (int i = Option.CHEAT; i < Option.CHEAT + Option.N_OPTS_CHEAT; i++)
                    {
                        Player_Other.instance.opt[Option.SCORE + (i - Option.CHEAT)] =
                            Player_Other.instance.opt[i];
                    }
                }
                else if (cmd.command == Command_Code.BUY_STAT)
                {
                    /* .choice is the stat to buy */
                    if (!rolled_stats)
                        buy_stat((Stat)cmd.arg[0].value, stats, points_spent, ref points_left);
                }
                else if (cmd.command == Command_Code.SELL_STAT)
                {
                    /* .choice is the stat to sell */
                    if (!rolled_stats)
                        sell_stat((Stat)cmd.arg[0].value, stats, points_spent, ref points_left);
                }
                else if (cmd.command == Command_Code.RESET_STATS)
                {
                    /* .choice is whether to regen stats */
                    reset_stats(stats, points_spent, ref points_left);

                    if (cmd.arg[0].value == 1)
                        generate_stats(stats, points_spent, ref points_left);

                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.ROLL_STATS)
                {
                    throw new NotImplementedException();
                    //int i;

                    //save_roller_data(&prev);

                    ///* Get a new character */
                    //get_stats(stats);

                    ///* Update stats with bonuses, etc. */
                    //get_bonuses();

                    ///* There's no real need to do this here, but it's tradition. */
                    //get_ahw(Player.Player.instance);
                    //Player.Player.instance.history = get_history(Player.Player.instance.race.history, &Player.Player.instance.sc);
                    //Player.Player.instance.sc_birth = Player.Player.instance.sc;

                    //event_signal(EVENT_GOLD);
                    //event_signal(EVENT_AC);
                    //event_signal(EVENT_HP);
                    //event_signal(EVENT_STATS);

                    ///* Give the UI some dummy info about the points situation. */
                    //points_left = 0;
                    //for (i = 0; i < A_MAX; i++)
                    //{
                    //    points_spent[i] = 0;
                    //}

                    //event_signal_birthpoints(points_spent, points_left);

                    ///* Lock out buying and selling of stats based on rolled stats. */
                    //rolled_stats = true;
                }
                else if (cmd.command == Command_Code.PREV_STATS)
                {
                    throw new NotImplementedException();
                    ///* Only switch to the stored "previous"
                    //   character if we've actually got one to load. */
                    //if (prev.age)
                    //{
                    //    load_roller_data(&prev, &prev);
                    //    get_bonuses();
                    //}

                    //event_signal(EVENT_GOLD);
                    //event_signal(EVENT_AC);
                    //event_signal(EVENT_HP);
                    //event_signal(EVENT_STATS);
                }
                else if (cmd.command == Command_Code.NAME_CHOICE)
                {
                    /* Set player name */
                    Player_Other.instance.full_name = cmd.arg[0].text;

                    //string_free((void *) cmd.arg[0].string);

                    /* Don't change savefile name.  If the UI wants it changed, they can do it. XXX (Good idea?) */
                    Files.process_player_name(false);
                }
                /* Various not-specific-to-birth commands. */
                else if (cmd.command == Command_Code.HELP)
                {
                    throw new NotImplementedException();
                    //char buf[80];

                    //strnfmt(buf, sizeof(buf), "birth.txt");
                    //screen_save();
                    //show_file(buf, null, 0, 0);
                    //screen_load();
                }
                else if (cmd.command == Command_Code.QUIT)
                {
                    Utilities.quit();
                }
            }

            roll_hp();

            Squelch.birth_init();

            /* Clear old messages, add new starting message */
            History.clear();
            History.add("Began the quest to destroy Morgoth.", History.PLAYER_BIRTH, null);

            /* Reset message prompt (i.e. no extraneous -more-s) */
            Term.msg_flag = true;

            /* Note player birth in the message recall */
            Message.add(" ", Message_Type.MSG_GENERIC);
            Message.add("  ", Message_Type.MSG_GENERIC);
            Message.add("====================", Message_Type.MSG_GENERIC);
            Message.add("  ", Message_Type.MSG_GENERIC);
            Message.add(" ", Message_Type.MSG_GENERIC);

            /* Give the player some money */
            get_money();

            /* Outfit the player, if they can sell the stuff */
            if (!Option.birth_no_selling.value) player_outfit(Player.Player.instance);

            /* Initialise the stores */
            Store.reset();

            /* Now we're really done.. */
            Game_Event.signal(Game_Event.Event_Type.LEAVE_BIRTH);
        }
예제 #14
0
        /*
         * Move player in the given direction.
         *
         * This routine should only be called when energy has been expended.
         *
         * Note that this routine handles monsters in the destination grid,
         * and also handles attempting to move into walls/doors/rubble/etc.
         */
        public static void move_player(int dir, bool disarm)
        {
            int py = Misc.p_ptr.py;
            int px = Misc.p_ptr.px;

            int y = py + Misc.ddy[dir];
            int x = px + Misc.ddx[dir];

            int m_idx = Cave.cave.m_idx[y][x];

            /* Attack monsters */
            if (m_idx > 0)
            {
                /* Mimics surprise the player */
                if (Monster.Monster.is_mimicking(m_idx))
                {
                    throw new NotImplementedException();
                    //become_aware(m_idx);

                    ///* Mimic wakes up */
                    //mon_clear_timed(m_idx, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE, false);
                }
                else
                {
                    Attack.py_attack(y, x);
                }
            }

            /* Optionally alter traps/doors on movement */
            else if (disarm && (Cave.cave.info[y][x] & Cave.CAVE_MARK) != 0 &&
                     (Cave.cave_isknowntrap(Cave.cave, y, x) ||
                      Cave.cave_iscloseddoor(Cave.cave, y, x)))
            {
                /* Auto-repeat if not already repeating */
                if (Game_Command.get_nrepeats() == 0)
                {
                    Game_Command.set_repeat(99);
                }

                Do_Command.alter_aux(dir);
            }

            /* Cannot walk through walls */
            else if (!Cave.cave_floor_bold(y, x))
            {
                /* Disturb the player */
                Cave.disturb(Misc.p_ptr, 0, 0);

                /* Notice unknown obstacles */
                if ((Cave.cave.info[y][x] & Cave.CAVE_MARK) == 0)
                {
                    /* Rubble */
                    if (Cave.cave.feat[y][x] == Cave.FEAT_RUBBLE)
                    {
                        Utilities.msgt(Message_Type.MSG_HITWALL, "You feel a pile of rubble blocking your way.");
                        Cave.cave.info[y][x] |= (Cave.CAVE_MARK);
                        Cave.cave_light_spot(Cave.cave, y, x);
                    }

                    /* Closed door */
                    else if (Cave.cave.feat[y][x] < Cave.FEAT_SECRET)
                    {
                        Utilities.msgt(Message_Type.MSG_HITWALL, "You feel a door blocking your way.");
                        Cave.cave.info[y][x] |= (Cave.CAVE_MARK);
                        Cave.cave_light_spot(Cave.cave, y, x);
                    }

                    /* Wall (or secret door) */
                    else
                    {
                        Utilities.msgt(Message_Type.MSG_HITWALL, "You feel a wall blocking your way.");
                        Cave.cave.info[y][x] |= (Cave.CAVE_MARK);
                        Cave.cave_light_spot(Cave.cave, y, x);
                    }
                }

                /* Mention known obstacles */
                else
                {
                    if (Cave.cave.feat[y][x] == Cave.FEAT_RUBBLE)
                    {
                        Utilities.msgt(Message_Type.MSG_HITWALL, "There is a pile of rubble blocking your way.");
                    }
                    else if (Cave.cave.feat[y][x] < Cave.FEAT_SECRET)
                    {
                        Utilities.msgt(Message_Type.MSG_HITWALL, "There is a door blocking your way.");
                    }
                    else
                    {
                        Utilities.msgt(Message_Type.MSG_HITWALL, "There is a wall blocking your way.");
                    }
                }
            }

            /* Normal movement */
            else
            {
                /* See if trap detection status will change */
                bool old_dtrap = ((Cave.cave.info2[py][px] & (Cave.CAVE2_DTRAP)) != 0);
                bool new_dtrap = ((Cave.cave.info2[y][x] & (Cave.CAVE2_DTRAP)) != 0);

                /* Note the change in the detect status */
                if (old_dtrap != new_dtrap)
                {
                    Misc.p_ptr.redraw |= (Misc.PR_DTRAP);
                }

                /* Disturb player if the player is about to leave the area */
                if (Option.disturb_detect.value && Misc.p_ptr.running != 0 &&
                    !Misc.p_ptr.running_firststep && old_dtrap && !new_dtrap)
                {
                    Cave.disturb(Misc.p_ptr, 0, 0);
                    return;
                }

                /* Move player */
                Monster.Monster.monster_swap(py, px, y, x);

                /* New location */
                y = py = Misc.p_ptr.py;
                x = px = Misc.p_ptr.px;

                /* Searching */
                if (Misc.p_ptr.searching != 0 || (Misc.p_ptr.state.skills[(int)Skill.SEARCH_FREQUENCY] >= 50) ||
                    Random.one_in_(50 - Misc.p_ptr.state.skills[(int)Skill.SEARCH_FREQUENCY]))
                {
                    search(false);
                }

                /* Handle "store doors" */
                if ((Cave.cave.feat[Misc.p_ptr.py][Misc.p_ptr.px] >= Cave.FEAT_SHOP_HEAD) &&
                    (Cave.cave.feat[Misc.p_ptr.py][Misc.p_ptr.px] <= Cave.FEAT_SHOP_TAIL))
                {
                    /* Disturb */
                    Cave.disturb(Misc.p_ptr, 0, 0);
                    Game_Command.insert(Command_Code.ENTER_STORE);
                }

                /* All other grids (including traps) */
                else
                {
                    /* Handle objects (later) */
                    Misc.p_ptr.notice |= (Misc.PN_PICKUP);
                }


                /* Discover invisible traps */
                if (Cave.cave.feat[y][x] == Cave.FEAT_INVIS)
                {
                    /* Disturb */
                    Cave.disturb(Misc.p_ptr, 0, 0);

                    /* Message */
                    Utilities.msg("You found a trap!");

                    /* Pick a trap */
                    Trap.pick_trap(y, x);

                    /* Hit the trap */
                    Trap.hit_trap(y, x);
                }

                /* Set off an visible trap */
                else if (Cave.cave_isknowntrap(Cave.cave, y, x))
                {
                    /* Disturb */
                    Cave.disturb(Misc.p_ptr, 0, 0);

                    throw new NotImplementedException();
                    /* Hit the trap */
                    //hit_trap(y, x);
                }
            }

            Misc.p_ptr.running_firststep = false;
        }
예제 #15
0
        /*
         * Prints Searching, Resting, or 'count' status
         * Display is always exactly 10 characters wide (see below)
         *
         * This function was a major bottleneck when resting, so a lot of
         * the text formatting code was optimized in place below.
         */
        static int prt_state(int row, int col)
        {
            ConsoleColor attr = ConsoleColor.White;

            string text = "";             //16


            /* Resting */
            if (Misc.p_ptr.resting != 0)
            {
                int i;
                int n = Misc.p_ptr.resting;

                /* Start with "Rest" */
                text = "Rest ";

                /* Extensive (timed) rest */
                if (n >= 1000)
                {
                    i = n / 100;

                    if (i >= 10)
                    {
                        int q = i / 10;
                        if (q >= 10)
                        {
                            text += Basic.I2D(q / 10);
                            //text[5] = Basic.I2D(q / 10);
                        }
                        else
                        {
                            text += " ";
                        }
                        text += Basic.I2D(q % 10);
                    }
                    else
                    {
                        text += " ";
                    }

                    text += Basic.I2D(i % 10) + "00";
                    //text[9] = '0';
                    //text[8] = '0';
                    //text[7] = I2D(i % 10);
                }

                /* Long (timed) rest */
                else if (n >= 100)
                {
                    text += "  ";
                    i     = n;
                    text += Basic.I2D(i / 100);
                    text += Basic.I2D((i / 10) % 10);
                    text += Basic.I2D(i % 10);
                    //text[9] = Basic.I2D(i % 10);
                    //i = i / 10;
                    //text[8] = Basic.I2D(i % 10);
                    //text[7] = Basic.I2D(i / 10);
                }

                /* Medium (timed) rest */
                else if (n >= 10)
                {
                    text += "   ";
                    i     = n;
                    text += Basic.I2D(i / 10);
                    text += Basic.I2D(i % 10);
                    //text[9] = I2D(i % 10);
                    //text[8] = I2D(i / 10);
                }

                /* Short (timed) rest */
                else if (n > 0)
                {
                    text += "    ";
                    i     = n;
                    text += Basic.I2D(i);
                    //text[9] = I2D(i);
                }

                /* Rest until healed */
                else if (n == -1)
                {
                    text += "*****";
                    //text[5] = text[6] = text[7] = text[8] = text[9] = '*';
                }

                /* Rest until done */
                else if (n == -2)
                {
                    text += "&&&&&";
                    //text[5] = text[6] = text[7] = text[8] = text[9] = '&';
                }

                /* Rest until HP or SP filled */
                else if (n == -3)
                {
                    text += "!!!!!";
                    //text[5] = text[6] = text[7] = text[8] = text[9] = '!';
                }
            }

            /* Repeating */
            else if (Game_Command.get_nrepeats() != 0)
            {
                int nrepeats = Game_Command.get_nrepeats();

                if (nrepeats > 999)
                {
                    text = "Rep. " + nrepeats / 100 + "00";
                }
                else
                {
                    text = "Repeat " + nrepeats;
                }
            }

            /* Searching */
            else if (Misc.p_ptr.searching != 0)
            {
                text = "Searching ";
            }

            /* Display the info (or blanks) */
            Utilities.c_put_str(attr, text, row, col);

            return(text.Length);
        }
예제 #16
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);
                }
            }
        }
예제 #17
0
        public static int get_birth_command(bool wait)
        {
            birth_stage next = current_stage;

            switch (current_stage)
            {
            case birth_stage.BIRTH_RESET:
            {
                Game_Command.insert(Command_Code.BIRTH_RESET);

                roller = birth_stage.BIRTH_RESET;

                if (quickstart_allowed)
                {
                    next = birth_stage.BIRTH_QUICKSTART;
                }
                else
                {
                    next = birth_stage.BIRTH_SEX_CHOICE;
                }

                break;
            }

            case birth_stage.BIRTH_QUICKSTART:
            {
                Files.display_player(0);
                next = get_quickstart_command();
                break;
            }

            case birth_stage.BIRTH_SEX_CHOICE:
            case birth_stage.BIRTH_CLASS_CHOICE:
            case birth_stage.BIRTH_RACE_CHOICE:
            case birth_stage.BIRTH_ROLLER_CHOICE:
            {
                Menu_Type    menu    = sex_menu;
                Command_Code command = Command_Code.CHOOSE_SEX;

                Term.clear();
                print_menu_instructions();

                if (current_stage > birth_stage.BIRTH_SEX_CHOICE)
                {
                    sex_menu.refresh(false);
                    menu    = race_menu;
                    command = Command_Code.CHOOSE_RACE;
                }

                if (current_stage > birth_stage.BIRTH_RACE_CHOICE)
                {
                    race_menu.refresh(false);
                    menu    = class_menu;
                    command = Command_Code.CHOOSE_CLASS;
                }

                if (current_stage > birth_stage.BIRTH_CLASS_CHOICE)
                {
                    class_menu.refresh(false);
                    menu    = roller_menu;
                    command = Command_Code.NULL;
                }

                next = menu_question(current_stage, menu, command);

                if (next == birth_stage.BIRTH_BACK)
                {
                    next = current_stage - 1;
                }

                /* Make sure that the character gets reset before quickstarting */
                if (next == birth_stage.BIRTH_QUICKSTART)
                {
                    next = birth_stage.BIRTH_RESET;
                }

                break;
            }

            case birth_stage.BIRTH_POINTBASED:
            {
                roller = birth_stage.BIRTH_POINTBASED;

                if (prev > birth_stage.BIRTH_POINTBASED)
                {
                    point_based_start();
                }

                next = point_based_command();

                if (next == birth_stage.BIRTH_BACK)
                {
                    next = birth_stage.BIRTH_ROLLER_CHOICE;
                }

                if (next != birth_stage.BIRTH_POINTBASED)
                {
                    point_based_stop();
                }

                break;
            }

            case birth_stage.BIRTH_ROLLER:
            {
                roller = birth_stage.BIRTH_ROLLER;
                next   = roller_command(prev < birth_stage.BIRTH_ROLLER);
                if (next == birth_stage.BIRTH_BACK)
                {
                    next = birth_stage.BIRTH_ROLLER_CHOICE;
                }

                break;
            }

            case birth_stage.BIRTH_NAME_CHOICE:
            {
                if (prev < birth_stage.BIRTH_NAME_CHOICE)
                {
                    Files.display_player(0);
                }

                next = get_name_command();
                if (next == birth_stage.BIRTH_BACK)
                {
                    next = roller;
                }

                break;
            }

            case birth_stage.BIRTH_FINAL_CONFIRM:
            {
                if (prev < birth_stage.BIRTH_FINAL_CONFIRM)
                {
                    Files.display_player(0);
                }

                next = get_confirm_command();
                if (next == birth_stage.BIRTH_BACK)
                {
                    next = birth_stage.BIRTH_NAME_CHOICE;
                }

                break;
            }
            }

            prev          = current_stage;
            current_stage = next;

            return(0);
        }
예제 #18
0
        /*
         * Returns the number of repeats left for the current command.
         * i.e. zero if not repeating.
         */
        public static int get_nrepeats()
        {
            Game_Command cmd = cmd_queue[prev_cmd_idx(cmd_tail)];

            return(cmd.nrepeats);
        }
예제 #19
0
        /* Allow the user to select from the current menu, and return the
         * corresponding command to the game.  Some actions are handled entirely
         * by the UI (displaying help text, for instance). */
        static birth_stage menu_question(birth_stage current, Menu_Type current_menu, Command_Code choice_command)
        {
            birthmenu_data menu_data = current_menu.menu_data as birthmenu_data;

            birth_stage next = birth_stage.BIRTH_RESET;

            /* Print the question currently being asked. */
            clear_question();
            Term.putstr(QUESTION_COL, QUESTION_ROW, -1, ConsoleColor.Yellow, menu_data.hint);

            current_menu.cmd_keys = "?=*\x18";                   /* ?, =, *, <ctl-X> */

            while (next == birth_stage.BIRTH_RESET)
            {
                /* Display the menu, wait for a selection of some sort to be made. */
                ui_event cx = current_menu.select(ui_event_type.EVT_KBRD, false);

                /* As all the menus are displayed in "hierarchical" style, we allow
                 * use of "back" (left arrow key or equivalent) to step back in
                 * the proces as well as "escape". */
                if (cx.type == ui_event_type.EVT_ESCAPE)
                {
                    next = birth_stage.BIRTH_BACK;
                }
                else if (cx.type == ui_event_type.EVT_SELECT)
                {
                    if (current == birth_stage.BIRTH_ROLLER_CHOICE)
                    {
                        Game_Command.insert(Command_Code.FINALIZE_OPTIONS);

                        if (current_menu.cursor != 0)
                        {
                            /* Do a first roll of the stats */
                            Game_Command.insert(Command_Code.ROLL_STATS);
                            next = current + 2;
                        }
                        else
                        {
                            /*
                             * Make sure we've got a point-based char to play with.
                             * We call point_based_start here to make sure we get
                             * an update on the points totals before trying to
                             * display the screen.  The call to CMD_RESET_STATS
                             * forces a rebuying of the stats to give us up-to-date
                             * totals.  This is, it should go without saying, a hack.
                             */
                            point_based_start();
                            Game_Command.insert(Command_Code.RESET_STATS);
                            Game_Command.get_top().set_arg_choice(0, 1);
                            next = current + 1;
                        }
                    }
                    else
                    {
                        Game_Command.insert(choice_command);
                        Game_Command.get_top().set_arg_choice(0, current_menu.cursor);
                        next = current + 1;
                    }
                }
                else if (cx.type == ui_event_type.EVT_KBRD)
                {
                    /* '*' chooses an option at random from those the game's provided. */
                    if (cx.key.code == (keycode_t)'*' && menu_data.allow_random)
                    {
                        current_menu.cursor = Random.randint0(current_menu.count);
                        Game_Command.insert(choice_command);
                        Game_Command.get_top().set_arg_choice(0, current_menu.cursor);
                        current_menu.refresh(false);
                        next = current + 1;
                    }
                    else if (cx.key.code == (keycode_t)'=')
                    {
                        Do_Command.options_birth();
                        next = current;
                    }
                    else if (cx.key.code == (keycode_t)UIEvent.KTRL('X'))
                    {
                        Game_Command.insert(Command_Code.QUIT);
                        next = birth_stage.BIRTH_COMPLETE;
                    }
                    else if (cx.key.code == (keycode_t)'?')
                    {
                        Do_Command.help();
                    }
                }
            }

            return(next);
        }
예제 #20
0
        static birth_stage point_based_command()
        {
            birth_stage next = birth_stage.BIRTH_POINTBASED;

            /*	point_based_display();*/
            /* Place cursor just after cost of current stat */
            /* Draw the Selection Cursor */
            new Region(COSTS_COL + 4, COSTS_ROW, 1, 6).erase();
            Utilities.put_str("<", COSTS_ROW + stat, COSTS_COL + 4);

            /* Get key */
            keypress ch = Utilities.inkey();

            if (ch.code == (keycode_t)UIEvent.KTRL('X'))
            {
                Game_Command.insert(Command_Code.QUIT);
                next = birth_stage.BIRTH_COMPLETE;
            }

            /* Go back a step, or back to the start of this step */
            else if (ch.code == keycode_t.ESCAPE)
            {
                next = birth_stage.BIRTH_BACK;
            }

            else if (ch.code == (keycode_t)'r' || ch.code == (keycode_t)'R')
            {
                Game_Command.insert(Command_Code.RESET_STATS);
                Game_Command.get_top().set_arg_choice(0, 0);
            }

            /* Done */
            else if ((ch.code == (keycode_t)'\r') || (ch.code == (keycode_t)'\n'))
            {
                next = birth_stage.BIRTH_NAME_CHOICE;
            }
            else
            {
                int dir = Utilities.target_dir(ch);

                /* Prev stat, looping round to the bottom when going off the top */
                if (dir == 8)
                {
                    stat = (stat + (int)Stat.Max - 1) % (int)Stat.Max;
                }

                /* Next stat, looping round to the top when going off the bottom */
                if (dir == 2)
                {
                    stat = (stat + 1) % (int)Stat.Max;
                }

                /* Decrease stat (if possible) */
                if (dir == 4)
                {
                    Game_Command.insert(Command_Code.SELL_STAT);
                    Game_Command.get_top().set_arg_choice(0, stat);
                }

                /* Increase stat (if possible) */
                if (dir == 6)
                {
                    Game_Command.insert(Command_Code.BUY_STAT);
                    Game_Command.get_top().set_arg_choice(0, stat);
                }
            }

            return(next);
        }
예제 #21
0
        /*
         * Create a new character.
         *
         * Note that we may be called with "junk" leftover in the various
         * fields, so we must be sure to clear them first.
         */
        public static void player_birth(bool quickstart_allowed)
        {
            Game_Command blank = new Game_Command(Command_Code.NULL, null, null, false, 0);
            Game_Command cmd   = blank;

            short[] stats        = new short[(int)Stat.Max];
            int[]   points_spent = new int[(int)Stat.Max];
            int     points_left  = 0;
            string  buf;
            int     success;

            bool rolled_stats = false;

            /*
             * The last character displayed, to allow the user to flick between two.
             * We rely on prev.age being zero to determine whether there is a stored
             * character or not, so initialise it here.
             */
            Birther prev = new Birther();

            /*
             * If quickstart is allowed, we store the old character in this,
             * to allow for it to be reloaded if we step back that far in the
             * birth process.
             */
            Birther quickstart_prev = new Birther();

            /*
             * If there's a quickstart character, store it for later use.
             * If not, default to whatever the first of the choices is.
             */
            if (quickstart_allowed)
            {
                quickstart_prev.save_roller_data();
            }
            else
            {
                Player.Player.instance.psex = 0;
                /* XXX default race/class */
                Player.Player.instance.Class = Misc.classes;
                Player.Player.instance.Race  = Misc.races;
                Player.Player.instance.generate(null, null, null);
            }

            /* Handle incrementing name suffix */
            buf = Utilities.find_roman_suffix_start(Player_Other.instance.full_name);

            if (buf != null)
            {
                /* Try to increment the roman suffix */
                success = Utilities.int_to_roman((Utilities.roman_to_int(buf) + 1), buf);

                if (success == 0)
                {
                    Utilities.msg("Sorry, could not deal with suffix");
                }
            }


            /* We're ready to start the interactive birth process. */
            Game_Event.signal_flag(Game_Event.Event_Type.ENTER_BIRTH, quickstart_allowed);

            /*
             * Loop around until the UI tells us we have an acceptable character.
             * Note that it is possible to quit from inside this loop.
             */
            while (cmd.command != Command_Code.ACCEPT_CHARACTER)
            {
                /* Grab a command from the queue - we're happy to wait for it. */
                if (Game_Command.get(cmd_context.CMD_BIRTH, ref cmd, true) == null)
                {
                    continue;
                }

                if (cmd.command == Command_Code.BIRTH_RESET)
                {
                    Player.Player.instance.generate(null, null, null);
                    reset_stats(stats, points_spent, ref points_left);
                    do_birth_reset(quickstart_allowed, quickstart_prev);
                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.CHOOSE_SEX)
                {
                    Player.Player.instance.psex = (byte)cmd.arg[0].value;
                    Player.Player.instance.generate(null, null, null);
                }
                else if (cmd.command == Command_Code.CHOOSE_RACE)
                {
                    Player.Player.instance.generate(null, Player_Race.player_id2race(cmd.arg[0].value), null);

                    reset_stats(stats, points_spent, ref points_left);
                    generate_stats(stats, points_spent, ref points_left);
                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.CHOOSE_CLASS)
                {
                    Player.Player.instance.generate(null, null, Player_Class.player_id2class(cmd.arg[0].value));

                    reset_stats(stats, points_spent, ref points_left);
                    generate_stats(stats, points_spent, ref points_left);
                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.FINALIZE_OPTIONS)
                {
                    /* Reset score options from cheat options */
                    for (int i = Option.CHEAT; i < Option.CHEAT + Option.N_OPTS_CHEAT; i++)
                    {
                        Player_Other.instance.opt[Option.SCORE + (i - Option.CHEAT)] =
                            Player_Other.instance.opt[i];
                    }
                }
                else if (cmd.command == Command_Code.BUY_STAT)
                {
                    /* .choice is the stat to buy */
                    if (!rolled_stats)
                    {
                        buy_stat((Stat)cmd.arg[0].value, stats, points_spent, ref points_left);
                    }
                }
                else if (cmd.command == Command_Code.SELL_STAT)
                {
                    /* .choice is the stat to sell */
                    if (!rolled_stats)
                    {
                        sell_stat((Stat)cmd.arg[0].value, stats, points_spent, ref points_left);
                    }
                }
                else if (cmd.command == Command_Code.RESET_STATS)
                {
                    /* .choice is whether to regen stats */
                    reset_stats(stats, points_spent, ref points_left);

                    if (cmd.arg[0].value == 1)
                    {
                        generate_stats(stats, points_spent, ref points_left);
                    }

                    rolled_stats = false;
                }
                else if (cmd.command == Command_Code.ROLL_STATS)
                {
                    throw new NotImplementedException();
                    //int i;

                    //save_roller_data(&prev);

                    ///* Get a new character */
                    //get_stats(stats);

                    ///* Update stats with bonuses, etc. */
                    //get_bonuses();

                    ///* There's no real need to do this here, but it's tradition. */
                    //get_ahw(Player.Player.instance);
                    //Player.Player.instance.history = get_history(Player.Player.instance.race.history, &Player.Player.instance.sc);
                    //Player.Player.instance.sc_birth = Player.Player.instance.sc;

                    //event_signal(EVENT_GOLD);
                    //event_signal(EVENT_AC);
                    //event_signal(EVENT_HP);
                    //event_signal(EVENT_STATS);

                    ///* Give the UI some dummy info about the points situation. */
                    //points_left = 0;
                    //for (i = 0; i < A_MAX; i++)
                    //{
                    //    points_spent[i] = 0;
                    //}

                    //event_signal_birthpoints(points_spent, points_left);

                    ///* Lock out buying and selling of stats based on rolled stats. */
                    //rolled_stats = true;
                }
                else if (cmd.command == Command_Code.PREV_STATS)
                {
                    throw new NotImplementedException();
                    ///* Only switch to the stored "previous"
                    //   character if we've actually got one to load. */
                    //if (prev.age)
                    //{
                    //    load_roller_data(&prev, &prev);
                    //    get_bonuses();
                    //}

                    //event_signal(EVENT_GOLD);
                    //event_signal(EVENT_AC);
                    //event_signal(EVENT_HP);
                    //event_signal(EVENT_STATS);
                }
                else if (cmd.command == Command_Code.NAME_CHOICE)
                {
                    /* Set player name */
                    Player_Other.instance.full_name = cmd.arg[0].text;

                    //string_free((void *) cmd.arg[0].string);

                    /* Don't change savefile name.  If the UI wants it changed, they can do it. XXX (Good idea?) */
                    Files.process_player_name(false);
                }
                /* Various not-specific-to-birth commands. */
                else if (cmd.command == Command_Code.HELP)
                {
                    throw new NotImplementedException();
                    //char buf[80];

                    //strnfmt(buf, sizeof(buf), "birth.txt");
                    //screen_save();
                    //show_file(buf, null, 0, 0);
                    //screen_load();
                }
                else if (cmd.command == Command_Code.QUIT)
                {
                    Utilities.quit();
                }
            }

            roll_hp();

            Squelch.birth_init();

            /* Clear old messages, add new starting message */
            History.clear();
            History.add("Began the quest to destroy Morgoth.", History.PLAYER_BIRTH, null);

            /* Reset message prompt (i.e. no extraneous -more-s) */
            Term.msg_flag = true;

            /* Note player birth in the message recall */
            Message.add(" ", Message_Type.MSG_GENERIC);
            Message.add("  ", Message_Type.MSG_GENERIC);
            Message.add("====================", Message_Type.MSG_GENERIC);
            Message.add("  ", Message_Type.MSG_GENERIC);
            Message.add(" ", Message_Type.MSG_GENERIC);

            /* Give the player some money */
            get_money();

            /* Outfit the player, if they can sell the stuff */
            if (!Option.birth_no_selling.value)
            {
                player_outfit(Player.Player.instance);
            }

            /* Initialise the stores */
            Store.reset();

            /* Now we're really done.. */
            Game_Event.signal(Game_Event.Event_Type.LEAVE_BIRTH);
        }
예제 #22
0
        /*
         * Insert the given command into the command queue.
         */
        static int cmd_insert_s(ref Game_Command cmd)
        {
            /* If queue full, return error */
            if (cmd_head + 1 == cmd_tail) return 1;
            if (cmd_head + 1 == CMD_QUEUE_SIZE && cmd_tail == 0) return 1;

            /* Insert command into queue. */
            if (cmd.command != Command_Code.REPEAT)
            {
                cmd_queue[cmd_head] = cmd;
            }
            else
            {
                int cmd_prev = cmd_head - 1;

                //was previously just "repeat_prev_allowed"
                if (!repeat_prev_allowed) return 1;

                /* If we're repeating a command, we duplicate the previous command
                   in the next command "slot". */
                if (cmd_prev < 0) cmd_prev = CMD_QUEUE_SIZE - 1;

                if (cmd_queue[cmd_prev].command != Command_Code.NULL)
                    cmd_queue[cmd_head] = cmd_queue[cmd_prev];
            }

            /* Advance point in queue, wrapping around at the end */
            cmd_head++;
            if (cmd_head == CMD_QUEUE_SIZE) cmd_head = 0;

            return 0;
        }
예제 #23
0
        /*
         * Inserts a command in the queue to be carried out, with the given
         * number of repeats.
         */
        public static int insert_repeated(Command_Code c, int nrepeats)
        {
            Game_Command cmd = new Game_Command();

            if (cmd_idx(c) == -1)
                return 1;

            cmd.command = c;
            cmd.nrepeats = nrepeats;

            return cmd_insert_s(ref cmd);
        }
예제 #24
0
        /*
         * Get the next game command, with 'wait' indicating whether we
         * are prepared to wait for a command or require a quick return with
         * no command.
         */
        public static Game_Command get(cmd_context c, ref Game_Command cmd, bool wait)
        {
            /* If we're repeating, just pull the last command again. */
            if (repeating)
            {
                cmd = cmd_queue[prev_cmd_idx(cmd_tail)];
                return cmd;
            }

            /* If there are no commands queued, ask the UI for one. */
            if (cmd_head == cmd_tail)
                cmd_get_hook(c, wait);

            /* If we have a command ready, set it and return success. */
            if (cmd_head != cmd_tail)
            {
                cmd = cmd_queue[cmd_tail++];
                if (cmd_tail == CMD_QUEUE_SIZE) cmd_tail = 0;

                return cmd;
            }

            /* Failure to get a command. */
            return null;
        }