/* * Start running. * * Note that running while confused is not allowed. */ void do_cmd_run(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; /* Hack XXX XXX XXX */ if (p_ptr->confused) { msg_print("You are too confused!"); return; } /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Verify legality */ if (!do_cmd_walk_test(y, x)) return; /* Start run */ run_step(dir); }
/* * Helper function for the "walk" and "jump" commands */ static void do_cmd_walk_or_jump(int pickup) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Verify legality */ if (!do_cmd_walk_test(y, x)) return; /* Take a turn */ p_ptr->energy_use = 100; /* Confuse direction */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; } /* Verify legality */ if (!do_cmd_walk_test(y, x)) return; /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* Move the player */ move_player(dir, pickup); }
void monk_double_attack_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Double Attack"); break; case SPELL_DESC: var_set_string(res, "Attack twice at an adjacent enemy. This action consumes double the normal energy."); break; case SPELL_CAST: var_set_bool(res, FALSE); if (_monk_check_spell()) { int x, y, dir = 0; if (!get_rep_dir(&dir, FALSE)) return; y = py + ddy[dir]; x = px + ddx[dir]; if (cave[y][x].m_idx) { if (one_in_(2)) msg_print("Ahhhtatatatatatatatatatatatatatataatatatatattaaaaa!!!!"); else msg_print("Oraoraoraoraoraoraoraoraoraoraoraoraoraoraoraoraora!!!!"); py_attack(y, x, 0); if (cave[y][x].m_idx) { handle_stuff(); py_attack(y, x, 0); } } else { msg_print("You don't see any monster in this direction"); msg_print(NULL); } var_set_bool(res, TRUE); } break; case SPELL_ENERGY: var_set_int(res, 100 + ENERGY_NEED()); break; default: default_spell(cmd, res); break; } }
/* Player controlled monsters */ bool do_control_walk(void) { /* Get a "repeated" direction */ if (p_ptr->control) { s32b dir; if (get_rep_dir(&dir)) { /* Take a turn */ energy_use = get_player_energy(SPEED_WALK); /* Actually move the monster */ p_ptr->control_dir = dir; } return TRUE; } else return FALSE; }
static bool _create_shots(void) { int x, y, dir, slot; cave_type *c_ptr; object_type forge; if (!get_rep_dir(&dir, FALSE)) return FALSE; y = py + ddy[dir]; x = px + ddx[dir]; c_ptr = &cave[y][x]; if (!have_flag(f_info[get_feat_mimic(c_ptr)].flags, FF_CAN_DIG)) { msg_print("You need pile of rubble."); return FALSE; } if (!cave_have_flag_grid(c_ptr, FF_CAN_DIG) || !cave_have_flag_grid(c_ptr, FF_HURT_ROCK)) { msg_print("You failed to make ammo."); return FALSE; } object_prep(&forge, lookup_kind(TV_SHOT, m_bonus(1, p_ptr->lev) + 1)); forge.number = (byte)rand_range(15,30); apply_magic(&forge, p_ptr->lev, AM_NO_FIXED_ART); obj_identify(&forge); forge.discount = 99; msg_print("You make some ammo."); slot = inven_carry(&forge); if (slot >= 0) autopick_alter_item(slot, FALSE); cave_alter_feat(y, x, FF_HURT_ROCK); p_ptr->update |= PU_FLOW; return TRUE; }
/* * Request a game command from the uI and carry out whatever actions * go along with it. */ void process_command(cmd_context ctx, bool no_request) { int idx; game_command cmd; /* If we've got a command to process, do it. */ if (cmd_get(ctx, &cmd, !no_request) == 0) { idx = cmd_idx(cmd.command); if (idx == -1) return; /* Do some sanity checking on those arguments that might have been declared as "unknown", such as directions and targets. */ switch (cmd.command) { case CMD_WALK: case CMD_RUN: case CMD_JUMP: case CMD_OPEN: case CMD_CLOSE: case CMD_TUNNEL: case CMD_DISARM: case CMD_BASH: case CMD_ALTER: case CMD_JAM: case CMD_MAKE_TRAP: { /* Direction hasn't been specified, so we ask for one. */ if (cmd.args[0].direction == DIR_UNKNOWN) { if (!get_rep_dir(&cmd.args[0].direction)) return; } 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 CMD_USE_WAND: case CMD_USE_ROD: case CMD_QUAFF: case CMD_ACTIVATE: case CMD_READ_SCROLL: case CMD_FIRE: case CMD_THROW: case CMD_STEAL: { bool get_target = FALSE; if (cmd.command == CMD_FIRE || cmd.command == CMD_THROW || obj_needs_aim(object_from_item_idx(cmd.args[0].choice))) { if (cmd.args[1].direction == DIR_UNKNOWN) get_target = TRUE; if (cmd.args[1].direction == DIR_TARGET && !target_okay()) get_target = TRUE; } if (get_target && !get_aim_dir(&cmd.args[1].direction, FALSE)) return; break; } /* This takes a choice and a direction. */ case CMD_CAST: { bool get_target = FALSE; if (spell_needs_aim(cp_ptr->spell_book, cmd.args[0].choice)) { if (cmd.args[1].direction == DIR_UNKNOWN) get_target = TRUE; if (cmd.args[1].direction == DIR_TARGET && !target_okay()) get_target = TRUE; } if (get_target && !get_aim_dir(&cmd.args[1].direction, FALSE)) return; break; } default: { /* I can see the point of the compiler warning, but still... */ break; } } /* Command repetition */ if (game_cmds[idx].repeat_allowed) { /* Auto-repeat */ if (game_cmds[idx].auto_repeat_n > 0 && p_ptr->command_arg == 0 && p_ptr->command_rep == 0) p_ptr->command_arg = game_cmds[idx].auto_repeat_n; allow_repeated_command(); } repeat_prev_allowed = TRUE; if (game_cmds[idx].fn) game_cmds[idx].fn(cmd.command, cmd.args); } }
/* * Manipulate an adjacent grid in some way * * Attack monsters, tunnel through walls, disarm traps, open doors, * or, for rogues, set traps and steal money. * * This command must always take energy, to prevent free detection * of invisible monsters. * * The "semantics" of this command must be chosen before the player * is confused, and it must be verified against the new grid. */ void do_cmd_alter(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; int feat; bool did_nothing = TRUE; bool more = FALSE; monster_type *m_ptr; /* Get a direction */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Original feature */ feat = cave_feat[y][x]; /* Must have knowledge to know feature XXX XXX */ if (!(cave_info[y][x] & (CAVE_MARK))) feat = FEAT_NONE; /* Take a turn */ p_ptr->energy_use = 100; /* Apply confusion */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; } /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* If a monster is present, and visible, Rogues may steal from it. * Otherwise, the player will simply attack. -LM- */ if (cave_m_idx[y][x] > 0) { if ((check_ability(SP_STEAL)) && (!SCHANGE)) { m_ptr = &m_list[cave_m_idx[y][x]]; if (m_ptr->ml) py_steal(y, x); else py_attack(y, x); } else py_attack(y, x); did_nothing = FALSE; } /* * Some players can set traps. Total number is checked in py_set_trap. */ else if ((check_ability(SP_TRAP)) && (cave_naked_bold(y, x))) { py_set_trap(y, x); did_nothing = FALSE; } /* Disarm advanced monster traps */ else if (feat > FEAT_MTRAP_HEAD) { /* Disarm */ more = do_cmd_disarm_aux(y, x); } /* Modify basic monster traps */ else if (feat == FEAT_MTRAP_HEAD) { /* Modify */ py_modify_trap(y, x); } /* Tunnel through walls */ else if (feat >= FEAT_SECRET) { /* Tunnel */ more = do_cmd_tunnel_aux(y, x); } /* Bash jammed doors */ else if (feat >= FEAT_DOOR_HEAD + 0x08) { /* Bash */ more = do_cmd_bash_aux(y, x); } /* Open closed doors */ else if (feat >= FEAT_DOOR_HEAD) { /* Close */ more = do_cmd_open_aux(y, x); } /* Disarm traps */ else if (feat >= FEAT_TRAP_HEAD) { /* Disarm */ more = do_cmd_disarm_aux(y, x); } /* Oops */ else if (did_nothing) { /* Oops */ msg_print("You spin around."); } /* Cancel repetition unless we can continue */ if (!more) disturb(0, 0); }
/* * Jam a closed door with a spike. Now takes only 4/10ths normal energy * if no monster is in the way. -LM- * * This command may NOT be repeated */ void do_cmd_spike(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir, item; /* Get a spike */ if (!get_spike(&item)) { /* Message */ msg_print("You have no spikes!"); /* Done */ return; } /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Verify legality */ if (!do_cmd_spike_test(y, x)) return; /* Take a partial turn. Now jamming is more useful. */ p_ptr->energy_use = 40; /* Confuse direction */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; } /* Monster. Make the action now take a full turn */ if (cave_m_idx[y][x] > 0) { /* Message */ msg_print("There is a monster in the way!"); p_ptr->energy_use += 60; /* Attack */ py_attack(y, x); } /* Go for it */ else { /* Verify legality */ if (!do_cmd_spike_test(y, x)) return; /* Successful jamming */ msg_print("You jam the door with a spike."); /* Convert "locked" to "stuck" XXX XXX XXX */ if (cave_feat[y][x] < FEAT_DOOR_HEAD + 0x08) { cave_feat[y][x] += 0x08; } /* Add one spike to the door */ if (cave_feat[y][x] < FEAT_DOOR_TAIL) { cave_feat[y][x] += 0x01; } /* Use up, and describe, a single spike, from the bottom */ inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } }
/* * Bash open a door, success based on character strength * * For a closed door, pval is positive if locked; negative if stuck. * * For an open door, pval is positive for a broken door. * * A closed door can be opened - harder if locked. Any door might be * bashed open (and thereby broken). Bashing a door is (potentially) * faster! You move into the door way. To open a stuck door, it must * be bashed. A closed door can be jammed (see do_cmd_spike()). * * Creatures can also open or bash doors, see elsewhere. */ void do_cmd_bash(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; bool more = FALSE; /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Verify legality */ if (!do_cmd_bash_test(y, x)) return; /* Take a turn */ p_ptr->energy_use = 100; /* Apply confusion */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; } /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* Monster */ if (cave_m_idx[y][x] > 0) { /* Message */ msg_print("There is a monster in the way!"); /* Attack */ py_attack(y, x); /* Done */ return; } /* Door */ else { /* Bash the door */ more = do_cmd_bash_aux(y, x); } /* Cancel repeat unless told not to */ if (!more) disturb(0, 0); }
/* * Disarms a trap, a glyph, or a chest. */ void do_cmd_disarm(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; s16b o_idx; bool more = FALSE; /* Option: Pick a direction -TNB- */ if (easy_disarm) { int num_traps, num_chests; /* Count visible traps */ num_traps = count_feats(&y, &x, is_trap, TRUE); /* Count chests (trapped) */ num_chests = count_chests(&y, &x, TRUE); /* See if there's only one target */ if (num_traps || num_chests) { if (num_traps + num_chests <= 1) p_ptr->command_dir = coords_to_dir(y, x); } } /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Check for chests */ o_idx = chest_check(y, x); /* Verify legality */ if (!o_idx && !do_cmd_disarm_test(y, x)) return; /* Take a turn */ p_ptr->energy_use = 100; /* Apply confusion */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Check for chests */ o_idx = chest_check(y, x); } /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* Monster */ if (cave_m_idx[y][x] > 0) { /* Message */ msg_print("There is a monster in the way!"); /* Attack */ py_attack(y, x); } /* Chest */ else if (o_idx) { /* Disarm the chest */ more = do_cmd_disarm_chest(y, x, o_idx); } /* Disarm trap */ else { /* Disarm the trap */ more = do_cmd_disarm_aux(y, x); } /* Cancel repeat unless told not to */ if (!more) disturb(0, 0); }
/* * Tunnel through "walls" (including rubble and secret doors) * * Digging is very difficult without a "digger" weapon, but can be * accomplished by strong players using heavy weapons. */ void do_cmd_tunnel(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; bool more = FALSE; /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Oops */ if (!do_cmd_tunnel_test(y, x)) return; /* Take a turn */ p_ptr->energy_use = 100; /* Apply confusion */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; } /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* Monster */ if (cave_m_idx[y][x] > 0) { /* Message */ msg_print("There is a monster in the way!"); /* Attack */ py_attack(y, x); } /* Walls */ else { /* Tunnel through walls */ more = do_cmd_tunnel_aux(y, x); } /* Cancel repetition unless we can continue */ if (!more) disturb(0, 0); }
/* * Close an open door. */ void do_cmd_close(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; bool more = FALSE; /* Option: Pick a direction -TNB- */ if (easy_open) { /* See if there's only one closeable door */ if (count_feats(&y, &x, is_open, FALSE) == 1) { p_ptr->command_dir = coords_to_dir(y, x); } } /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Verify legality */ if (!do_cmd_close_test(y, x)) return; /* Take a turn */ p_ptr->energy_use = 100; /* Apply confusion */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; } /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* Monster */ if (cave_m_idx[y][x] > 0) { /* Message */ msg_print("There is a monster in the way!"); /* Attack */ py_attack(y, x); } /* Door */ else { /* Close door */ more = do_cmd_close_aux(y, x); } /* Cancel repeat unless told not to */ if (!more) disturb(0, 0); }
static void cmd_racial_power_aux(const mutation_type *mut_ptr) { s16b plev = p_ptr->lev; int dir = 0; if (racial_aux(mut_ptr->level, mut_ptr->cost, mut_ptr->stat, mut_ptr->diff)) { switch (p_ptr->prace) { case RACE_DWARF: { msg_print("You examine your surroundings."); (void)detect_traps(); (void)detect_doors(); (void)detect_stairs(); break; } case RACE_HOBBIT: { object_type *q_ptr; object_type forge; /* Get local object */ q_ptr = &forge; /* Create the food ration */ object_prep(q_ptr, 21); /* Drop the object from heaven */ (void)drop_near(q_ptr, -1, p_ptr->py, p_ptr->px); msg_print("You cook some food."); break; } case RACE_GNOME: { msg_print("Blink!"); teleport_player(10 + plev); break; } case RACE_HALF_ORC: { msg_print("You play tough."); (void)set_afraid(0); break; } case RACE_HALF_TROLL: { msg_print("RAAAGH!"); if (!p_ptr->shero) { (void)hp_player(30); } (void)set_afraid(0); (void)set_shero(p_ptr->shero + 10 + randint1(plev)); break; } case RACE_AMBERITE: { /* Hack - use levels to choose ability */ if (mut_ptr->level == 30) { msg_print("You picture the Pattern in your mind and walk it..."); (void)set_poisoned(0); (void)set_image(0); (void)set_stun(0); (void)set_cut(0); (void)set_blind(0); (void)set_afraid(0); (void)do_res_stat(A_STR, 200); (void)do_res_stat(A_INT, 200); (void)do_res_stat(A_WIS, 200); (void)do_res_stat(A_DEX, 200); (void)do_res_stat(A_CON, 200); (void)do_res_stat(A_CHR, 200); (void)restore_level(); } else if (mut_ptr->level == 40) { /* No effect in arena or quest */ if (p_ptr->inside_quest) { msg_print("There is no effect."); } else { msg_print("You start walking around. Your surroundings change."); if (autosave_l) do_cmd_save_game(TRUE); /* Leaving */ p_ptr->leaving = TRUE; } } break; } case RACE_BARBARIAN: { msg_print("Raaagh!"); if (!p_ptr->shero) { (void)hp_player(30); } (void)set_afraid(0); (void)set_shero(p_ptr->shero + 10 + randint1(plev)); break; } case RACE_HALF_OGRE: { msg_print("You carefully set an explosive rune..."); (void)explosive_rune(); break; } case RACE_HALF_GIANT: { if (!get_aim_dir(&dir)) break; msg_print("You bash at a stone wall."); (void)wall_to_mud(dir); break; } case RACE_HALF_TITAN: { msg_print("You examine your foes..."); (void)probing(); break; } case RACE_CYCLOPS: { if (!get_aim_dir(&dir)) break; msg_print("You throw a huge boulder."); (void)fire_bolt(GF_MISSILE, dir, (3 * plev) / 2); break; } case RACE_YEEK: { if (!get_aim_dir(&dir)) break; msg_print("You make a horrible scream!"); (void)fear_monster(dir, plev); break; } case RACE_KLACKON: { if (!get_aim_dir(&dir)) break; msg_print("You spit acid."); if (plev < 25) (void)fire_bolt(GF_ACID, dir, plev); else (void)fire_ball(GF_ACID, dir, plev, 2); break; } case RACE_KOBOLD: { if (!get_aim_dir(&dir)) break; msg_print("You throw a dart of poison."); (void)fire_bolt(GF_POIS, dir, plev); break; } case RACE_NIBELUNG: { msg_print("You examine your surroundings."); (void)detect_traps(); (void)detect_doors(); (void)detect_stairs(); break; } case RACE_DARK_ELF: { if (!get_aim_dir(&dir)) break; msg_print("You cast a magic missile."); (void)fire_bolt_or_beam(10, GF_MISSILE, dir, damroll(3 + ((plev - 1) / 5), 4)); break; } case RACE_DRACONIAN: { int Type = (one_in_(3) ? GF_COLD : GF_FIRE); cptr Type_desc = ((Type == GF_COLD) ? "cold" : "fire"); if (randint1(100) < plev) { switch (p_ptr->pclass) { case CLASS_WARRIOR: case CLASS_RANGER: if (one_in_(3)) { Type = GF_MISSILE; Type_desc = "the elements"; } else { Type = GF_SHARDS; Type_desc = "shards"; } break; case CLASS_MAGE: case CLASS_WARRIOR_MAGE: case CLASS_HIGH_MAGE: if (one_in_(3)) { Type = GF_MANA; Type_desc = "mana"; } else { Type = GF_DISENCHANT; Type_desc = "disenchantment"; } break; case CLASS_CHAOS_WARRIOR: if (!one_in_(3)) { Type = GF_CONFUSION; Type_desc = "confusion"; } else { Type = GF_CHAOS; Type_desc = "chaos"; } break; case CLASS_MONK: if (!one_in_(3)) { Type = GF_CONFUSION; Type_desc = "confusion"; } else { Type = GF_SOUND; Type_desc = "sound"; } break; case CLASS_MINDCRAFTER: if (!one_in_(3)) { Type = GF_CONFUSION; Type_desc = "confusion"; } else { Type = GF_PSI; Type_desc = "mental energy"; } break; case CLASS_PRIEST: case CLASS_PALADIN: if (one_in_(3)) { Type = GF_HELL_FIRE; Type_desc = "hellfire"; } else { Type = GF_HOLY_FIRE; Type_desc = "holy fire"; } break; case CLASS_ROGUE: if (one_in_(3)) { Type = GF_DARK; Type_desc = "darkness"; } else { Type = GF_POIS; Type_desc = "poison"; } break; } } if (!get_aim_dir(&dir)) break; msg_format("You breathe %s.", Type_desc); (void)fire_ball(Type, dir, plev * 2, (plev / 15) + 1); break; } case RACE_MIND_FLAYER: { if (!get_aim_dir(&dir)) break; else { msg_print("You concentrate and your eyes glow red..."); (void)fire_bolt(GF_PSI, dir, plev); } break; } case RACE_IMP: { if (!get_aim_dir(&dir)) break; if (plev >= 30) { msg_print("You cast a ball of fire."); (void)fire_ball(GF_FIRE, dir, plev, 2); } else { msg_print("You cast a bolt of fire."); (void)fire_bolt(GF_FIRE, dir, plev); } break; } case RACE_GOLEM: { (void)set_shield(p_ptr->shield + rand_range(30, 50)); break; } case RACE_SKELETON: case RACE_ZOMBIE: { msg_print("You attempt to restore your lost energies."); (void)restore_level(); break; } case RACE_VAMPIRE: { int y, x, dummy; cave_type *c_ptr; /* Only works on adjacent monsters */ if (!get_rep_dir(&dir)) break; y = p_ptr->py + ddy[dir]; x = p_ptr->px + ddx[dir]; /* Paranoia */ if (!in_bounds2(y, x)) break; c_ptr = area(y, x); if (!c_ptr->m_idx) { msg_print("You bite into thin air!"); break; } msg_print("You grin and bare your fangs..."); dummy = plev + randint1(plev) * MAX(1, plev / 10); /* Dmg */ if (drain_gain_life(dir, dummy)) { /* Gain nutritional sustenance: 150/hp drained */ /* A Food ration gives 5000 food points (by contrast) */ /* Don't ever get more than "Full" this way */ /* But if we ARE Gorged, it won't cure us */ dummy = p_ptr->food + MIN(5000, 100 * dummy); if (p_ptr->food < PY_FOOD_MAX) /* Not gorged already */ (void)set_food(dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy); } else msg_print("Yechh. That tastes foul."); break; } case RACE_SPECTRE: { msg_print("You emit an eldritch howl!"); if (!get_aim_dir(&dir)) break; (void)fear_monster(dir, plev); break; } case RACE_SPRITE: { msg_print("You throw some magic dust..."); if (plev < 25) (void)sleep_monsters_touch(); else (void)sleep_monsters(); break; } case RACE_GHOUL: { if (mut_ptr->level == 30) { /* Sense living */ (void)detect_monsters_living(); } else { eat_corpse(); } break; } default: msg_print("This race has no bonus power."); p_ptr->energy_use = 0; } } /* Redraw mana and hp */ p_ptr->redraw |= (PR_HP | PR_MANA); /* Window stuff */ p_ptr->window |= (PW_PLAYER | PW_SPELL); }