/* Set up one of our menus ready to display choices for a birth question. * This is slightly involved. */ static void init_birth_menu(ref Menu_Type menu, int n_choices, int initial_choice, Region reg, bool allow_random, Menu_Type.browse_hook_func aux) { birthmenu_data menu_data; /* Initialise a basic menu */ menu = new Menu_Type(Menu_Type.skin_id.SCROLL, birth_iter); /* A couple of behavioural flags - we want selections letters in * lower case and a double tap to act as a selection. */ menu.selections = TextUI.lower_case; menu.flags = (int)Menu_Type.menu_type_flags.MN_DBL_TAP; /* Copy across the game's suggested initial selection, etc. */ menu.cursor = initial_choice; /* Allocate sufficient space for our own bits of menu information. */ menu_data = new birthmenu_data(); /* Allocate space for an array of menu item texts and help texts * (where applicable) */ menu_data.items = new string[n_choices]; menu_data.allow_random = allow_random; /* Set private data */ menu.priv(n_choices, menu_data); /* Set up the "browse" hook to display help text (where applicable). */ menu.browse_hook = aux; /* Lay out the menu appropriately */ menu.layout(reg); }
/* A custom "display" function for our menus that simply displays the * text from our stored data in a different colour if it's currently * selected. */ static void birthmenu_display(Menu_Type menu, int oid, bool cursor, int row, int col, int width) { birthmenu_data data = menu.menu_data as birthmenu_data; ConsoleColor attr = Menu_Type.curs_attrs[(int)Menu_Type.CURS.KNOWN][cursor?1:0]; Utilities.c_put_str(attr, data.items[oid], row, col); }
/* 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); }