/* * 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); } } }
/* * 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; }
/* * 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); }