/* * 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); }
static void race_help(int i, object db, Region l) { int j; int k; Player_Race r = Player_Race.player_id2race(i); int len = ((int)Stat.Max + 1) / 2; int n_flags = 0; int flag_space = 3; if (r == null) { return; } /* Output to the screen */ Misc.text_out_hook = Utilities.text_out_to_screen; /* Indent output */ Misc.text_out_indent = RACE_AUX_COL; Term.gotoxy(RACE_AUX_COL, TABLE_ROW); for (j = 0; j < len; j++) { string name1 = Stat_Names.Reduced[j]; string name2 = Stat_Names.Reduced[j + len]; int adj1 = r.r_adj[j]; int adj2 = r.r_adj[j + len]; Utilities.text_out_e("{0}{1} {2}{3}\n", name1, (adj1 > 0? "+" + adj1 : adj1.ToString()).PadLeft(3, ' '), name2, (adj2 > 0? "+" + adj2 : adj2.ToString()).PadLeft(3, ' ')); } Utilities.text_out_e("\n"); skill_help(r.r_skills, r.r_mhp, r.r_exp, r.infra); Utilities.text_out_e("\n"); for (k = 0; k < Object_Flag.MAX.value; k++) { if (n_flags >= flag_space) { break; } if (!r.flags.has(k)) { continue; } Utilities.text_out_e("\n{0}", get_flag_desc(k)); n_flags++; } for (k = 0; k < Misc.PF.MAX.value; k++) { if (n_flags >= flag_space) { break; } if (!r.pflags.has(k)) { continue; } Utilities.text_out_e("\n%s", get_pflag_desc(k)); n_flags++; } while (n_flags < flag_space) { Utilities.text_out_e("\n"); n_flags++; } /* Reset text_out() indentation */ Misc.text_out_indent = 0; }