public static void wr_object_memory() { wr_u16b(Misc.z_info.k_max); for (int k_idx = 0; k_idx < Misc.z_info.k_max; k_idx++) { byte tmp8u = 0; Object_Kind k_ptr = Misc.k_info[k_idx]; if (k_ptr == null) { k_ptr = new Object_Kind(); } if (k_ptr.aware) { tmp8u |= 0x01; } if (k_ptr.tried) { tmp8u |= 0x02; } if (Squelch.kind_is_squelched_aware(k_ptr)) { tmp8u |= 0x04; } if (k_ptr.everseen) { tmp8u |= 0x08; } if (Squelch.kind_is_squelched_unaware(k_ptr)) { tmp8u |= 0x10; } wr_byte(tmp8u); } }
/* * Update the current "run" path * * Return true if the running should be stopped */ static bool run_test() { int py = Misc.p_ptr.py; int px = Misc.p_ptr.px; int prev_dir; int new_dir; int row, col; int i, max; bool inv; int option, option2; /* No options yet */ option = 0; option2 = 0; /* Where we came from */ prev_dir = Misc.p_ptr.run_old_dir; /* Range of newly adjacent grids */ max = (prev_dir & 0x01) + 1; /* Look at every newly adjacent square. */ for (i = -max; i <= max; i++) { Object.Object o_ptr; /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = py + Misc.ddy[new_dir]; col = px + Misc.ddx[new_dir]; /* Visible monsters abort running */ if (Cave.cave.m_idx[row][col] > 0) { Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[row][col]); /* Visible monster */ if (m_ptr.ml) { return(true); } } /* Visible objects abort running */ for (o_ptr = Object.Object.get_first_object(row, col); o_ptr != null; o_ptr = Object.Object.get_next_object(o_ptr)) { /* Visible object */ if (o_ptr.marked != 0 && !Squelch.item_ok(o_ptr)) { return(true); } } /* Assume unknown */ inv = true; /* Check memorized grids */ if ((Cave.cave.info[row][col] & (Cave.CAVE_MARK)) != 0) { bool notice = true; /* Examine the terrain */ switch (Cave.cave.feat[row][col]) { /* Floors */ case Cave.FEAT_FLOOR: /* Invis traps */ case Cave.FEAT_INVIS: /* Secret doors */ case Cave.FEAT_SECRET: /* Normal veins */ case Cave.FEAT_MAGMA: case Cave.FEAT_QUARTZ: /* Hidden treasure */ case Cave.FEAT_MAGMA_H: case Cave.FEAT_QUARTZ_H: /* Walls */ case Cave.FEAT_WALL_EXTRA: case Cave.FEAT_WALL_INNER: case Cave.FEAT_WALL_OUTER: case Cave.FEAT_WALL_SOLID: case Cave.FEAT_PERM_EXTRA: case Cave.FEAT_PERM_INNER: case Cave.FEAT_PERM_OUTER: case Cave.FEAT_PERM_SOLID: { /* Ignore */ notice = false; /* Done */ break; } } /* Interesting feature */ if (notice) { return(true); } /* The grid is "visible" */ inv = false; } /* Analyze unknown grids and floors */ if (inv || Cave.cave_floor_bold(row, col)) { /* Looking for open area */ if (Misc.p_ptr.run_open_area) { /* Nothing */ } /* The first new direction. */ else if (option == 0) { option = new_dir; } /* Three new directions. Stop running. */ else if (option2 != 0) { return(true); } /* Two non-adjacent new directions. Stop running. */ else if (option != cycle[chome[prev_dir] + i - 1]) { return(true); } /* Two new (adjacent) directions (case 1) */ else if ((new_dir & 0x01) != 0) { option2 = new_dir; } /* Two new (adjacent) directions (case 2) */ else { option2 = option; option = new_dir; } } /* Obstacle, while looking for open area */ else { if (Misc.p_ptr.run_open_area) { if (i < 0) { /* Break to the right */ Misc.p_ptr.run_break_right = true; } else if (i > 0) { /* Break to the left */ Misc.p_ptr.run_break_left = true; } } } } /* Look at every soon to be newly adjacent square. */ for (i = -max; i <= max; i++) { /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = py + Misc.ddy[prev_dir] + Misc.ddy[new_dir]; col = px + Misc.ddx[prev_dir] + Misc.ddx[new_dir]; /* HACK: Ugh. Sometimes we come up with illegal bounds. This will * treat the symptom but not the disease. */ if (row >= Cave.DUNGEON_HGT || col >= Cave.DUNGEON_WID) { continue; } if (row < 0 || col < 0) { continue; } /* Visible monsters abort running */ if (Cave.cave.m_idx[row][col] > 0) { Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[row][col]); /* Visible monster */ if (m_ptr.ml) { return(true); } } } /* Looking for open area */ if (Misc.p_ptr.run_open_area) { /* Hack -- look again */ for (i = -max; i < 0; i++) { new_dir = cycle[chome[prev_dir] + i]; row = py + Misc.ddy[new_dir]; col = px + Misc.ddx[new_dir]; /* Unknown grid or non-wall */ /* Was: cave_floor_bold(row, col) */ if ((Cave.cave.info[row][col] & (Cave.CAVE_MARK)) == 0 || (Cave.cave.feat[row][col] < Cave.FEAT_SECRET)) { /* Looking to break right */ if (Misc.p_ptr.run_break_right) { return(true); } } /* Obstacle */ else { /* Looking to break left */ if (Misc.p_ptr.run_break_left) { return(true); } } } /* Hack -- look again */ for (i = max; i > 0; i--) { new_dir = cycle[chome[prev_dir] + i]; row = py + Misc.ddy[new_dir]; col = px + Misc.ddx[new_dir]; /* Unknown grid or non-wall */ /* Was: cave_floor_bold(row, col) */ if ((Cave.cave.info[row][col] & (Cave.CAVE_MARK)) == 0 || (Cave.cave.feat[row][col] < Cave.FEAT_SECRET)) { /* Looking to break left */ if (Misc.p_ptr.run_break_left) { return(true); } } /* Obstacle */ else { /* Looking to break right */ if (Misc.p_ptr.run_break_right) { return(true); } } } } /* Not looking for open area */ else { /* No options */ if (option == 0) { return(true); } /* One option */ else if (option2 == 0) { /* Primary option */ Misc.p_ptr.run_cur_dir = (short)option; /* No other options */ Misc.p_ptr.run_old_dir = (short)option; } /* Two options, examining corners */ else { /* Primary option */ Misc.p_ptr.run_cur_dir = (short)option; /* Hack -- allow curving */ Misc.p_ptr.run_old_dir = (short)option2; } } /* About to hit a known wall, stop */ if (see_wall(Misc.p_ptr.run_cur_dir, py, px)) { return(true); } /* Failure */ return(false); }
/*** Pickup ***/ /* * Pickup all gold at the player's current location. */ static void py_pickup_gold() { int py = Misc.p_ptr.py; int px = Misc.p_ptr.px; int total_gold = 0; byte[] treasure; short this_o_idx = 0; short next_o_idx = 0; Object.Object o_ptr; Message_Type sound_msg; bool verbal = false; /* Allocate an array of ordinary gold objects */ treasure = new byte[(int)Object.SVal.sval_gold.SV_GOLD_MAX]; /* Pick up all the ordinary gold objects */ for (this_o_idx = Cave.cave.o_idx[py][px]; this_o_idx != 0; this_o_idx = next_o_idx) { /* Get the object */ o_ptr = Object.Object.byid(this_o_idx); if (o_ptr == null) { break; } /* Get the next object */ next_o_idx = o_ptr.next_o_idx; /* Ignore if not legal treasure */ if ((o_ptr.tval != TVal.TV_GOLD) || (o_ptr.sval >= (int)SVal.sval_gold.SV_GOLD_MAX)) { continue; } /* Note that we have this kind of treasure */ treasure[o_ptr.sval]++; /* Remember whether feedback message is in order */ if (!Squelch.item_ok(o_ptr)) { verbal = true; } /* Increment total value */ total_gold += (int)o_ptr.pval[Misc.DEFAULT_PVAL]; /* Delete the gold */ Object.Object.delete_object_idx(this_o_idx); } /* Pick up the gold, if present */ if (total_gold != 0) { //char buf[1024]; //char tmp[80]; string buf; string tmp; int i, count, total; Object_Kind kind; /* Build a message */ buf = String.Format("You have found {0} gold pieces worth of ", total_gold); /* Count the types of treasure present */ for (total = 0, i = 0; i < (int)SVal.sval_gold.SV_GOLD_MAX; i++) { if (treasure[i] != 0) { total++; } } /* List the treasure types */ for (count = 0, i = 0; i < (int)SVal.sval_gold.SV_GOLD_MAX; i++) { /* Skip if no treasure of this type */ if (treasure[i] == 0) { continue; } /* Get this object index */ kind = Object_Kind.lookup_kind(TVal.TV_GOLD, i); if (kind == null) { continue; } /* Get the object name */ tmp = Object.Object.object_kind_name(kind, true); /* Build up the pickup string */ buf = buf + tmp; /* Added another kind of treasure */ count++; /* Add a comma if necessary */ if ((total > 2) && (count < total)) { buf += ","; } /* Add an "and" if necessary */ if ((total >= 2) && (count == total - 1)) { buf += " and"; } /* Add a space or period if necessary */ if (count < total) { buf += " "; } else { buf += "."; } } /* Determine which sound to play */ if (total_gold < 200) { sound_msg = Message_Type.MSG_MONEY1; } else if (total_gold < 600) { sound_msg = Message_Type.MSG_MONEY2; } else { sound_msg = Message_Type.MSG_MONEY3; } /* Display the message */ if (verbal) { Utilities.msgt(sound_msg, "{0}", buf); } /* Add gold to purse */ Misc.p_ptr.au += total_gold; /* Redraw gold */ Misc.p_ptr.redraw |= (Misc.PR_GOLD); } /* Free the gold array */ //FREE(treasure); }
public static int do_autopickup() { int py = Misc.p_ptr.py; int px = Misc.p_ptr.px; short this_o_idx, next_o_idx = 0; Object.Object o_ptr; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; int floor_num = 0; int[] floor_list = new int[Misc.MAX_FLOOR_STACK + 1]; /* Nothing to pick up -- return */ if (Cave.cave.o_idx[py][px] == 0) { return(0); } /* Always pickup gold, effortlessly */ py_pickup_gold(); /* Scan the remaining objects */ for (this_o_idx = Cave.cave.o_idx[py][px]; this_o_idx != 0; this_o_idx = next_o_idx) { /* Get the object and the next object */ o_ptr = Object.Object.byid(this_o_idx); if (o_ptr == null) { break; } next_o_idx = o_ptr.next_o_idx; /* Ignore all hidden objects and non-objects */ if (Squelch.item_ok(o_ptr) || o_ptr.kind == null) { continue; } /* XXX Hack -- Enforce limit */ if (floor_num >= floor_list.Length) { break; } /* Hack -- disturb */ Cave.disturb(Misc.p_ptr, 0, 0); throw new NotImplementedException(); ///* Automatically pick up items into the backpack */ //if (auto_pickup_okay(o_ptr)) //{ // /* Pick up the object with message */ // py_pickup_aux(this_o_idx, true); // objs_picked_up++; // continue; //} ///* Tally objects and store them in an array. */ ///* Remember this object index */ //floor_list[floor_num] = this_o_idx; ///* Count non-gold objects that remain on the floor. */ //floor_num++; } return(objs_picked_up); }
/* * 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); }
/* * Identify an item. * * `item` is used to print the slot occupied by an object in equip/inven. * Any negative value assigned to "item" can be used for specifying an object * on the floor. */ public static void do_ident_item(int item, Object.Object o_ptr) { string o_name = ""; //80 Message_Type msg_type = (Message_Type)0; int i; bool bad = true; /* Identify it */ o_ptr.flavor_aware(); o_ptr.notice_everything(); /* Apply an autoinscription, if necessary */ Squelch.apply_autoinscription(o_ptr); /* Set squelch flag */ Misc.p_ptr.notice |= (int)Misc.PN_SQUELCH; /* Recalculate bonuses */ Misc.p_ptr.update |= (Misc.PU_BONUS); /* Combine / Reorder the pack (later) */ Misc.p_ptr.notice |= (int)(Misc.PN_COMBINE | Misc.PN_REORDER | Misc.PN_SORT_QUIVER); /* Window stuff */ Misc.p_ptr.redraw |= (Misc.PR_INVEN | Misc.PR_EQUIP); /* Description */ o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL); /* Determine the message type. */ /* CC: we need to think more carefully about how we define "bad" with * multiple pvals - currently using "all nonzero pvals < 0" */ for (i = 0; i < o_ptr.num_pvals; i++) { if (o_ptr.pval[i] > 0) { bad = false; } } if (bad) { msg_type = Message_Type.MSG_IDENT_BAD; } else if (o_ptr.artifact != null) { msg_type = Message_Type.MSG_IDENT_ART; } else if (o_ptr.ego != null) { msg_type = Message_Type.MSG_IDENT_EGO; } else { msg_type = Message_Type.MSG_GENERIC; } /* Log artifacts to the history list. */ if (o_ptr.artifact != null) { History.add_artifact(o_ptr.artifact, true, true); } /* Describe */ if (item >= Misc.INVEN_WIELD) { Utilities.msgt(msg_type, "{0}: {1} ({2}).", Object.Object.describe_use(item), o_name, Object.Object.index_to_label(item)); //Utilities.msgt(msg_type, "%^s: %s (%c).", describe_use(item), o_name, index_to_label(item)); } else if (item >= 0) { Utilities.msgt(msg_type, "In your pack: {0} ({1}).", o_name, Object.Object.index_to_label(item)); //Utilities.msgt(msg_type, "In your pack: %s (%c).", o_name, index_to_label(item)); } else { Utilities.msgt(msg_type, "On the ground: {0}.", o_name); } }
/* * Initialize some other arrays */ static Parser.Error init_other() { /*** Prepare the various "bizarre" arrays ***/ /* Initialize the "quark" package */ Quark.Init(); /* Initialize squelch things */ Squelch.Init(); TextUI.knowledge_init(); /* Initialize the "message" package */ Message.Init(); /*** Prepare grid arrays ***/ /* Array of grids */ Misc.temp_g = new ushort[Misc.TEMP_MAX]; Cave.instance = new Cave(); /* Array of stacked monster messages */ Monster_Message.mon_msg = new Monster_Race_Message[Misc.MAX_STORED_MON_MSG]; Monster_Message.mon_message_hist = new Monster_Message_History[Misc.MAX_STORED_MON_CODES]; /*** Prepare "vinfo" array ***/ /* Used by "update_view()" */ Cave.vinfo_init(); /*** Prepare entity arrays ***/ /* Objects */ Object.Object.Init(); /*** Prepare lore array ***/ /* Lore */ Misc.l_list = new Monster_Lore[Misc.z_info.r_max]; /*** Prepare mouse buttons ***/ Button.Init(Button.add_text, Button.kill_text); /*** Prepare quest array ***/ /* Quests */ Misc.q_list = new Quest[Misc.MAX_Q_IDX]; /*** Prepare the inventory ***/ /* Allocate it */ Player.Player.instance.inventory = new Object.Object[Misc.ALL_INVEN_TOTAL]; for (int i = 0; i < Player.Player.instance.inventory.Count(); i++) { Player.Player.instance.inventory[i] = new Object.Object(); } /*** Prepare the options ***/ Option.set_defaults(); /* Initialize the window flags */ for (int i = 0; i < Misc.ANGBAND_TERM_MAX; i++) { /* Assume no flags */ Player_Other.instance.window_flag[i] = (uint)0L; //God damn it, who wrote that?!?! -werror should be on!!! } /*** Pre-allocate space for the "format()" buffer ***/ //Nick: Not needed in C# /* Hack -- Just call the "format()" function */ //format("I wish you could swim, like dolphins can swim..."); /* Success */ return(0); }