static void shift_btn(shifter_dd *dt, void **wdata, int what, void **where) { int i; if ((what == op_EVT_OK) || (what == op_EVT_CANCEL)) { shift_play_state = FALSE; // Stop mem_pal_copy(mem_pal, dt->old_pal); update_stuff(UPD_PAL); run_destroy(wdata); return; } if (what == op_EVT_CHANGE) // Play toggle { cmd_read(where, dt); if (shift_play_state && !shift_timer_state) // Start timer shift_timer_state = threads_timeout_add(100, shift_play_timer_call, dt); return; } where = origin_slot(where); if (where == dt->fix) // Button to fix palette pressed { i = dt->frame[0]; if (!i || (i > dt->frame[2])) return; // Nothing to do mem_pal_copy(mem_pal, dt->old_pal); spot_undo(UNDO_PAL); shifter_set_palette(dt, i); mem_pal_copy(dt->old_pal, mem_pal); cmd_set(dt->slider, 0); update_stuff(UPD_PAL); } else if (where == dt->clear) // Button to clear all of the values { for (i = 0; i < NSHIFT; i++) spins[i][0][0] = spins[i][1][0] = spins[i][2][0] = 0; cmd_reset(dt->spinpack, dt); shifter_moved(dt, wdata, op_EVT_CHANGE, dt->spinpack); } else if (where == dt->create) // Button to create a sequence of undo images { if (!dt->frame[2]) return; // Nothing to do for (i = 0; i <= dt->frame[2]; i++) { shifter_set_palette(dt, i); spot_undo(UNDO_PAL); } shifter_set_palette(dt, dt->frame[0]); update_stuff(UPD_PAL); } }
/*! * @brief プレイヤーの職業を変更する * @return なし * @todo 魔法領域の再選択などがまだ不完全、要実装。 */ static void do_cmd_wiz_reset_class(void) { int tmp_int; char tmp_val[160]; char ppp[80]; /* Prompt */ sprintf(ppp, "Class (0-%d): ", MAX_CLASS - 1); /* Default */ sprintf(tmp_val, "%d", p_ptr->pclass); /* Query */ if (!get_string(ppp, tmp_val, 2)) return; /* Extract */ tmp_int = atoi(tmp_val); /* Verify */ if (tmp_int < 0 || tmp_int >= MAX_CLASS) return; /* Save it */ p_ptr->pclass = tmp_int; /* Redraw inscription */ p_ptr->window |= (PW_PLAYER); /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); update_stuff(); }
/** * Take off a non-cursed equipment item * * Note that taking off an item when "full" may cause that item * to fall to the ground. * * Note also that this function does not try to combine the taken off item * with other inventory items - that must be done by the calling function. */ void inven_takeoff(struct object *obj) { int slot = equipped_item_slot(player->body, obj); const char *act; char o_name[80]; /* Paranoia */ if (slot == player->body.count) return; /* Describe the object */ object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); /* Describe removal by slot */ if (slot_type_is(slot, EQUIP_WEAPON)) act = "You were wielding"; else if (slot_type_is(slot, EQUIP_BOW)) act = "You were holding"; else if (slot_type_is(slot, EQUIP_LIGHT)) act = "You were holding"; else act = "You were wearing"; /* De-equip the object */ player->body.slots[slot].obj = NULL; player->upkeep->equip_cnt--; /* Message */ msgt(MSG_WIELD, "%s %s (%c).", act, o_name, I2A(slot)); player->upkeep->update |= (PU_BONUS | PU_INVEN | PU_UPDATE_VIEW); player->upkeep->notice |= (PN_IGNORE); update_stuff(player); return; }
/** * This routine will "darken" all grids in the set passed in. * * In addition, some of these grids will be "unmarked". * * This routine is used (only) by "light_room()" */ static void cave_unlight(struct point_set *ps) { int i; /* Apply flag changes */ for (i = 0; i < ps->n; i++) { int y = ps->pts[i].y; int x = ps->pts[i].x; /* Darken the grid */ sqinfo_off(cave->squares[y][x].info, SQUARE_GLOW); /* Hack -- Forget "boring" grids */ if (square_isfloor(cave, y, x)) sqinfo_off(cave->squares[y][x].info, SQUARE_MARK); } /* Fully update the visuals */ player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Update stuff */ update_stuff(player); /* Process the grids */ for (i = 0; i < ps->n; i++) { int y = ps->pts[i].y; int x = ps->pts[i].x; /* Redraw the grid */ square_light_spot(cave, y, x); } }
static void shifter_slider_moved(shifter_dd *dt, void **wdata, int what, void **where) { cmd_read(where, dt); shifter_set_palette(dt, dt->frame[0]); update_stuff(UPD_PAL); }
/* * Handle "p_ptr->update" and "p_ptr->redraw" */ void handle_stuff(void) { /* Update stuff */ if (p_ptr->update) update_stuff(); /* Redraw stuff */ if (p_ptr->redraw) redraw_stuff(); }
/** * Housekeeping on leaving a level */ static void on_leave_level(void) { /* Any pending processing */ notice_stuff(player); update_stuff(player); redraw_stuff(player); /* Flush messages */ event_signal(EVENT_MESSAGE_FLUSH); }
static gboolean click_shift_close() // Palette Shifter window closed by user or WM { shift_play_stop(); mem_pal_copy( mem_pal, sh_old_pal ); update_stuff(UPD_PAL); destroy_dialog(shifter_window); return (FALSE); }
/* * Change player's "movement" setting */ void do_cmd_change_movement(s32b i) { p_ptr->movement += i; if (p_ptr->movement > 8) p_ptr->movement = 0; if (p_ptr->movement < 0) p_ptr->movement = 8; p_ptr->update |= (PU_BONUS); update_stuff(); prt("", 0, 0); }
/* * Change player's "tactic" setting */ void do_cmd_change_tactic(s32b i) { p_ptr->tactic += i; if (p_ptr->tactic > 8) p_ptr->tactic = 0; if (p_ptr->tactic < 0) p_ptr->tactic = 8; p_ptr->update |= (PU_BONUS); update_stuff(); prt("", 0, 0); }
static void shifter_slider_moved() // Slider position changed { int pos = mt_spinslide_read_value(shifter_slider); if ( pos != shifter_pos ) { shifter_pos = pos; shifter_set_palette(pos); update_stuff(UPD_PAL); } }
/* * Handle "p_ptr->update" and "p_ptr->redraw" and "p_ptr->window" */ void handle_stuff(void) { /* Update stuff */ if (p_ptr->update) update_stuff(); /* Redraw stuff */ if (flag_used(&p_ptr->redraw)) redraw_stuff(); /* Window stuff */ if (flag_used(&p_ptr->window)) window_stuff(); }
/** * This routine will Perma-Light all grids in the set passed in. * * This routine is used (only) by "light_room()" * * Dark grids are illuminated. * * Also, process all affected monsters. * * SMART monsters always wake up when illuminated * NORMAL monsters wake up 1/4 the time when illuminated * STUPID monsters wake up 1/10 the time when illuminated */ static void cave_light(struct point_set *ps) { int i; /* Apply flag changes */ for (i = 0; i < ps->n; i++) { int y = ps->pts[i].y; int x = ps->pts[i].x; /* Perma-Light */ sqinfo_on(cave->squares[y][x].info, SQUARE_GLOW); } /* Fully update the visuals */ player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Update stuff */ update_stuff(player); /* Process the grids */ for (i = 0; i < ps->n; i++) { int y = ps->pts[i].y; int x = ps->pts[i].x; /* Redraw the grid */ square_light_spot(cave, y, x); /* Process affected monsters */ if (cave->squares[y][x].mon > 0) { int chance = 25; monster_type *m_ptr = square_monster(cave, y, x); /* Stupid monsters rarely wake up */ if (rf_has(m_ptr->race->flags, RF_STUPID)) chance = 10; /* Smart monsters always wake up */ if (rf_has(m_ptr->race->flags, RF_SMART)) chance = 100; /* Sometimes monsters wake up */ if (m_ptr->m_timed[MON_TMD_SLEEP] && (randint0(100) < chance)) { /* Wake up! */ mon_clear_timed(m_ptr, MON_TMD_SLEEP, MON_TMD_FLG_NOTIFY, FALSE); } } } }
/** * Housekeeping after the processing of a player command */ static void process_player_cleanup(void) { int i; /* Significant */ if (player->upkeep->energy_use) { /* Use some energy */ player->energy -= player->upkeep->energy_use; /* Increment the total energy counter */ player->total_energy += player->upkeep->energy_use; /* Do nothing else if player has auto-dropped stuff */ if (!player->upkeep->dropping) { /* Hack -- constant hallucination */ if (player->timed[TMD_IMAGE]) player->upkeep->redraw |= (PR_MAP); /* Shimmer multi-hued monsters */ for (i = 1; i < cave_monster_max(cave); i++) { struct monster *mon = cave_monster(cave, i); if (!mon->race) continue; if (!rf_has(mon->race->flags, RF_ATTR_MULTI)) continue; square_light_spot(cave, mon->fy, mon->fx); } /* Clear NICE flag, and show marked monsters */ for (i = 1; i < cave_monster_max(cave); i++) { struct monster *mon = cave_monster(cave, i); mflag_off(mon->mflag, MFLAG_NICE); if (mflag_has(mon->mflag, MFLAG_MARK)) { if (!mflag_has(mon->mflag, MFLAG_SHOW)) { mflag_off(mon->mflag, MFLAG_MARK); update_mon(mon, cave, false); } } } } } /* Clear SHOW flag and player drop status */ for (i = 1; i < cave_monster_max(cave); i++) { struct monster *mon = cave_monster(cave, i); mflag_off(mon->mflag, MFLAG_SHOW); } player->upkeep->dropping = false; /* Hack - update needed first because inventory may have changed */ update_stuff(player); redraw_stuff(player); }
/** * Overflow an item from the pack, if it is overfull. */ void pack_overflow(struct object *obj) { int i; char o_name[80]; bool artifact = false; if (!pack_is_overfull()) return; /* Disturbing */ disturb(player, 0); /* Warning */ msg("Your pack overflows!"); /* Get the last proper item */ for (i = 1; i <= z_info->pack_size; i++) if (!player->upkeep->inven[i]) break; /* Drop the last inventory item unless requested otherwise */ if (!obj) { obj = player->upkeep->inven[i - 1]; } /* Rule out weirdness (like pack full, but inventory empty) */ assert(obj != NULL); /* Describe */ object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); if (obj->artifact) { artifact = true; } /* Message */ msg("You drop %s.", o_name); /* Excise the object and drop it (carefully) near the player */ gear_excise_object(obj); drop_near(cave, &obj, 0, player->py, player->px, false); /* Describe */ if (artifact) msg("You no longer have the %s.", o_name); else msg("You no longer have %s.", o_name); /* Notice, update, redraw */ if (player->upkeep->notice) notice_stuff(player); if (player->upkeep->update) update_stuff(player); if (player->upkeep->redraw) redraw_stuff(player); }
/** * Overflow an item from the pack, if it is overfull. */ void pack_overflow(void) { int i; struct object *obj = NULL; char o_name[80]; if (!pack_is_overfull()) return; /* Disturbing */ disturb(player, 0); /* Warning */ msg("Your pack overflows!"); /* Find the last inventory item */ for (i = 1; i <= z_info->pack_size; i++) if (!player->upkeep->inven[i]) break; /* Last object was the previous index */ obj = player->upkeep->inven[i - 1]; /* Rule out weirdness (like pack full, but inventory empty) */ assert(obj != NULL); /* Describe */ object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); /* Message */ msg("You drop %s (%c).", o_name, I2A(i - 1)); /* Excise the object and drop it (carefully) near the player */ gear_excise_object(obj); drop_near(cave, obj, 0, player->py, player->px, FALSE); /* Describe */ if (obj->artifact) msg("You no longer have the %s (%c).", o_name, I2A(i - 1)); else msg("You no longer have %s (%c).", o_name, I2A(i - 1)); /* Notice stuff (if needed) */ if (player->upkeep->notice) notice_stuff(player->upkeep); /* Update stuff (if needed) */ if (player->upkeep->update) update_stuff(player->upkeep); /* Redraw stuff (if needed) */ if (player->upkeep->redraw) redraw_stuff(player->upkeep); }
static void click_shift_fix() // Button to fix palette pressed { int i = mt_spinslide_get_value(shifter_slider); if ( i==0 || i>=shifter_max ) return; // Nothing to do mem_pal_copy( mem_pal, sh_old_pal ); spot_undo(UNDO_PAL); shifter_set_palette(i); mem_pal_copy( sh_old_pal, mem_pal ); mt_spinslide_set_value(shifter_slider, 0); update_stuff(UPD_PAL); }
static void click_shift_create() // Button to create a sequence of undo images { int i; if ( shifter_max<2 ) return; // Nothing to do for ( i=0; i<shifter_max; i++ ) { shifter_set_palette(i); spot_undo(UNDO_PAL); } shifter_set_palette( mt_spinslide_get_value(shifter_slider) ); update_stuff(UPD_PAL); }
/** * Housekeeping on arriving on a new level */ void on_new_level(void) { /* Play ambient sound on change of level. */ play_ambient_sound(); /* Cancel the target */ target_set_monster(0); /* Cancel the health bar */ health_track(player->upkeep, NULL); /* Disturb */ disturb(player, 1); /* Track maximum player level */ if (player->max_lev < player->lev) player->max_lev = player->lev; /* Track maximum dungeon level */ if (player->max_depth < player->depth) player->max_depth = player->depth; /* Flush messages */ event_signal(EVENT_MESSAGE_FLUSH); /* Update display */ event_signal(EVENT_NEW_LEVEL_DISPLAY); /* Update player */ update_player_object_knowledge(player); player->upkeep->update |= (PU_BONUS | PU_HP | PU_SPELLS | PU_INVEN); player->upkeep->notice |= (PN_COMBINE | PN_SEARCH); notice_stuff(player); update_stuff(player); redraw_stuff(player); /* Refresh */ event_signal(EVENT_REFRESH); /* Announce (or repeat) the feeling */ if (player->depth) display_feeling(false); /* Give player minimum energy to start a new level, but do not reduce * higher value from savefile for level in progress */ if (player->energy < z_info->move_energy) player->energy = z_info->move_energy; }
/** * Illuminate or darken any room containing the given location. */ void light_room(int y1, int x1, bool light) { int i, x, y; struct point_set *ps; ps = point_set_new(200); /* Add the initial grid */ cave_room_aux(ps, y1, x1); /* While grids are in the queue, add their neighbors */ for (i = 0; i < ps->n; i++) { x = ps->pts[i].x, y = ps->pts[i].y; /* Walls get lit, but stop light */ if (!square_isprojectable(cave, y, x)) continue; /* Spread adjacent */ cave_room_aux(ps, y + 1, x); cave_room_aux(ps, y - 1, x); cave_room_aux(ps, y, x + 1); cave_room_aux(ps, y, x - 1); /* Spread diagonal */ cave_room_aux(ps, y + 1, x + 1); cave_room_aux(ps, y - 1, x - 1); cave_room_aux(ps, y - 1, x + 1); cave_room_aux(ps, y + 1, x - 1); } /* Now, lighten or darken them all at once */ if (light) { cave_light(ps); } else { cave_unlight(ps); } point_set_dispose(ps); /* Fully update the visuals */ player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Update stuff */ update_stuff(player); }
/** * Cure everything instantly */ static void do_cmd_wiz_cure_all(void) { /* Restore stats */ (void) res_stat(A_STR); (void) res_stat(A_INT); (void) res_stat(A_WIS); (void) res_stat(A_CON); (void) res_stat(A_DEX); (void) res_stat(A_CHR); /* Restore the level */ (void) restore_level(); /* Update stuff (if needed) */ if (p_ptr->update) update_stuff(p_ptr); /* Heal the player */ p_ptr->chp = p_ptr->mhp; p_ptr->chp_frac = 0; /* Restore mana */ p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; /* Cure stuff */ (void) clear_timed(TMD_BLIND, TRUE); (void) clear_timed(TMD_CONFUSED, TRUE); (void) clear_timed(TMD_POISONED, TRUE); (void) clear_timed(TMD_AFRAID, TRUE); (void) clear_timed(TMD_PARALYZED, TRUE); (void) clear_timed(TMD_IMAGE, TRUE); (void) clear_timed(TMD_STUN, TRUE); (void) clear_timed(TMD_CUT, TRUE); (void) clear_timed(TMD_SLOW, TRUE); p_ptr->black_breath = FALSE; /* No longer hungry */ (void) set_food(PY_FOOD_MAX - 1); /* Redraw everything */ do_cmd_redraw(); }
static void _shatter_device_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Shatter Device"); break; case SPELL_DESC: var_set_string(res, "Destroy a magical device in your inventory for various effects."); break; case SPELL_CAST: { int item; object_type *o_ptr; var_set_bool(res, FALSE); item_tester_hook = object_is_device; if (!get_item(&item, "Shatter which device?", "You have nothing to shatter.", USE_INVEN)) return; o_ptr = &inventory[item]; var_set_bool(res, TRUE); if (o_ptr->activation.type == EFFECT_NONE) { msg_print("Nothing happens."); } else if (o_ptr->activation.type == EFFECT_DESTRUCTION) { if (destroy_area(py, px, 15 + p_ptr->lev + randint0(11), 4 * p_ptr->lev)) msg_print("The dungeon collapses..."); else msg_print("The dungeon trembles."); } else if ( o_ptr->activation.type == EFFECT_HEAL_CURING || o_ptr->activation.type == EFFECT_HEAL_CURING_HERO || o_ptr->activation.type == EFFECT_RESTORING ) { msg_print("You feel life flow through your body!"); restore_level(); (void)set_poisoned(0, TRUE); (void)set_blind(0, TRUE); (void)set_confused(0, TRUE); (void)set_image(0, TRUE); (void)set_stun(0, TRUE); (void)set_cut(0, TRUE); (void)do_res_stat(A_STR); (void)do_res_stat(A_CON); (void)do_res_stat(A_DEX); (void)do_res_stat(A_WIS); (void)do_res_stat(A_INT); (void)do_res_stat(A_CHR); update_stuff(); /* hp may change if Con was drained ... */ hp_player(5000); } else if ( o_ptr->activation.type == EFFECT_TELEPORT_AWAY || o_ptr->activation.type == EFFECT_BANISH_EVIL || o_ptr->activation.type == EFFECT_BANISH_ALL ) { banish_monsters(p_ptr->lev * 4); } else { project(0, 5, py, px, o_ptr->activation.difficulty * 16, _object_dam_type(o_ptr), PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL, -1); } inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); break; } default: default_spell(cmd, res); break; } }
/* * Do an effect, given an object. * Boost is the extent to which skill surpasses difficulty, used as % boost. It * ranges from 0 to 138. */ bool effect_do(effect_type effect, bool *ident, bool aware, int dir, int beam, int boost) { int py = p_ptr->py; int px = p_ptr->px; int dam, chance, dur; if (effect < 1 || effect > EF_MAX) { msg("Bad effect passed to do_effect(). Please report this bug."); return FALSE; } switch (effect) { case EF_POISON: { inc_timed(TMD_POISONED, damroll(2, 7) + 10, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_BLIND: { inc_timed(TMD_BLIND, damroll(4, 25) + 75, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_SCARE: { inc_timed(TMD_AFRAID, randint0(10) + 10, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_CONFUSE: { inc_timed(TMD_CONFUSED, damroll(4, 5) + 10, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_HALLUC: { inc_timed(TMD_IMAGE, randint0(250) + 250, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_PARALYZE: { inc_timed(TMD_PARALYZED, randint0(5) + 5, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_SLOW: { if (inc_timed(TMD_SLOW, randint1(25) + 15, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_POISON: { if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_BLINDNESS: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_PARANOIA: { if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_CONFUSION: { if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_MIND: { if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (clear_timed(TMD_IMAGE, TRUE)) *ident = TRUE; if (!of_has(p_ptr->state.flags, OF_RES_CONFU) && inc_timed(TMD_OPP_CONF, damroll(4, 10), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_BODY: { if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_LIGHT: { if (hp_player(20)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (dec_timed(TMD_CUT, 20, TRUE)) *ident = TRUE; if (dec_timed(TMD_CONFUSED, 20, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_SERIOUS: { if (hp_player(40)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_CRITICAL: { if (hp_player(60)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_AMNESIA, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_FULL: { int amt = (p_ptr->mhp * 35) / 100; if (amt < 300) amt = 300; if (hp_player(amt)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_AMNESIA, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_FULL2: { if (hp_player(1200)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_AMNESIA, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_TEMP: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_HEAL1: { if (hp_player(500)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_HEAL2: { if (hp_player(1000)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_HEAL3: { if (hp_player(500)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_GAIN_EXP: { if (p_ptr->exp < PY_MAX_EXP) { msg("You feel more experienced."); player_exp_gain(p_ptr, 100000L); *ident = TRUE; } return TRUE; } case EF_LOSE_EXP: { if (!check_state(OF_HOLD_LIFE, p_ptr->state.flags) && (p_ptr->exp > 0)) { msg("You feel your memories fade."); player_exp_lose(p_ptr, p_ptr->exp / 4, FALSE); *ident = TRUE; } *ident = TRUE; wieldeds_notice_flag(OF_HOLD_LIFE); return TRUE; } case EF_RESTORE_EXP: { if (restore_level()) *ident = TRUE; return TRUE; } case EF_RESTORE_MANA: { if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; msg("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); *ident = TRUE; } return TRUE; } case EF_GAIN_STR: case EF_GAIN_INT: case EF_GAIN_WIS: case EF_GAIN_DEX: case EF_GAIN_CON: case EF_GAIN_CHR: { int stat = effect - EF_GAIN_STR; if (do_inc_stat(stat)) *ident = TRUE; return TRUE; } case EF_GAIN_ALL: { if (do_inc_stat(A_STR)) *ident = TRUE; if (do_inc_stat(A_INT)) *ident = TRUE; if (do_inc_stat(A_WIS)) *ident = TRUE; if (do_inc_stat(A_DEX)) *ident = TRUE; if (do_inc_stat(A_CON)) *ident = TRUE; if (do_inc_stat(A_CHR)) *ident = TRUE; return TRUE; } case EF_BRAWN: { /* Pick a random stat to decrease other than strength */ int stat = randint0(A_MAX-1) + 1; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_STR); *ident = TRUE; } return TRUE; } case EF_INTELLECT: { /* Pick a random stat to decrease other than intelligence */ int stat = randint0(A_MAX-1); if (stat >= A_INT) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_INT); *ident = TRUE; } return TRUE; } case EF_CONTEMPLATION: { /* Pick a random stat to decrease other than wisdom */ int stat = randint0(A_MAX-1); if (stat >= A_WIS) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_WIS); *ident = TRUE; } return TRUE; } case EF_TOUGHNESS: { /* Pick a random stat to decrease other than constitution */ int stat = randint0(A_MAX-1); if (stat >= A_CON) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_CON); *ident = TRUE; } return TRUE; } case EF_NIMBLENESS: { /* Pick a random stat to decrease other than dexterity */ int stat = randint0(A_MAX-1); if (stat >= A_DEX) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_DEX); *ident = TRUE; } return TRUE; } case EF_PLEASING: { /* Pick a random stat to decrease other than charisma */ int stat = randint0(A_MAX-1); if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_CHR); *ident = TRUE; } return TRUE; } case EF_LOSE_STR: case EF_LOSE_INT: case EF_LOSE_WIS: case EF_LOSE_DEX: case EF_LOSE_CON: case EF_LOSE_CHR: { int stat = effect - EF_LOSE_STR; take_hit(damroll(5, 5), "stat drain"); (void)do_dec_stat(stat, FALSE); *ident = TRUE; return TRUE; } case EF_LOSE_CON2: { take_hit(damroll(10, 10), "poisonous food"); (void)do_dec_stat(A_CON, FALSE); *ident = TRUE; return TRUE; } case EF_RESTORE_STR: case EF_RESTORE_INT: case EF_RESTORE_WIS: case EF_RESTORE_DEX: case EF_RESTORE_CON: case EF_RESTORE_CHR: { int stat = effect - EF_RESTORE_STR; if (do_res_stat(stat)) *ident = TRUE; return TRUE; } case EF_CURE_NONORLYBIG: { msg("You feel life flow through your body!"); restore_level(); (void)clear_timed(TMD_POISONED, TRUE); (void)clear_timed(TMD_BLIND, TRUE); (void)clear_timed(TMD_CONFUSED, TRUE); (void)clear_timed(TMD_IMAGE, TRUE); (void)clear_timed(TMD_STUN, TRUE); (void)clear_timed(TMD_CUT, TRUE); (void)clear_timed(TMD_AMNESIA, TRUE); if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; /* Recalculate max. hitpoints */ update_stuff(); hp_player(5000); *ident = TRUE; return TRUE; } case EF_RESTORE_ALL: { /* Life, above, also gives these effects */ if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; return TRUE; } case EF_RESTORE_ST_LEV: { if (restore_level()) *ident = TRUE; if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; return TRUE; } case EF_TMD_INFRA: { if (inc_timed(TMD_SINFRA, 100 + damroll(4, 25), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_TMD_SINVIS: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (inc_timed(TMD_SINVIS, 12 + damroll(2, 6), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_TMD_ESP: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (inc_timed(TMD_TELEPATHY, 12 + damroll(6, 6), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_ENLIGHTENMENT: { msg("An image of your surroundings forms in your mind..."); wiz_light(); *ident = TRUE; return TRUE; } case EF_ENLIGHTENMENT2: { msg("You begin to feel more enlightened..."); message_flush(); wiz_light(); (void)do_inc_stat(A_INT); (void)do_inc_stat(A_WIS); (void)detect_traps(TRUE); (void)detect_doorstairs(TRUE); (void)detect_treasure(TRUE); identify_pack(); *ident = TRUE; return TRUE; } case EF_HERO: { dur = randint1(25) + 25; if (hp_player(10)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (inc_timed(TMD_BOLD, dur, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_HERO, dur, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_SHERO: { dur = randint1(25) + 25; if (hp_player(30)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (inc_timed(TMD_BOLD, dur, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_SHERO, dur, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_ACID: { if (inc_timed(TMD_OPP_ACID, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_ELEC: { if (inc_timed(TMD_OPP_ELEC, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_FIRE: { if (inc_timed(TMD_OPP_FIRE, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_COLD: { if (inc_timed(TMD_OPP_COLD, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_POIS: { if (inc_timed(TMD_OPP_POIS, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_ALL: { if (inc_timed(TMD_OPP_ACID, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_ELEC, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_FIRE, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_COLD, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_POIS, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_DETECT_TREASURE: { if (detect_treasure(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_TRAP: { if (detect_traps(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_DOORSTAIR: { if (detect_doorstairs(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_INVIS: { if (detect_monsters_invis(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_EVIL: { if (detect_monsters_evil(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_ALL: { if (detect_all(aware)) *ident = TRUE; return TRUE; } case EF_ENCHANT_TOHIT: { *ident = TRUE; return enchant_spell(1, 0, 0); } case EF_ENCHANT_TODAM: { *ident = TRUE; return enchant_spell(0, 1, 0); } case EF_ENCHANT_WEAPON: { *ident = TRUE; return enchant_spell(randint1(3), randint1(3), 0); } case EF_ENCHANT_ARMOR: { *ident = TRUE; return enchant_spell(0, 0, 1); } case EF_ENCHANT_ARMOR2: { *ident = TRUE; return enchant_spell(0, 0, randint1(3) + 2); } case EF_RESTORE_ITEM: { *ident = TRUE; return restore_item(); } case EF_IDENTIFY: { *ident = TRUE; if (!ident_spell()) return FALSE; return TRUE; } case EF_REMOVE_CURSE: { if (remove_curse()) { if (!p_ptr->timed[TMD_BLIND]) msg("The air around your body glows blue for a moment..."); else msg("You feel as if someone is watching over you."); *ident = TRUE; } return TRUE; } case EF_REMOVE_CURSE2: { remove_all_curse(); *ident = TRUE; return TRUE; } case EF_LIGHT: { if (light_area(damroll(2, 8), 2)) *ident = TRUE; return TRUE; } case EF_SUMMON_MON: { int i; sound(MSG_SUM_MONSTER); for (i = 0; i < randint1(3); i++) { if (summon_specific(py, px, p_ptr->depth, 0, 1)) *ident = TRUE; } return TRUE; } case EF_SUMMON_UNDEAD: { int i; sound(MSG_SUM_UNDEAD); for (i = 0; i < randint1(3); i++) { if (summon_specific(py, px, p_ptr->depth, S_UNDEAD, 1)) *ident = TRUE; } return TRUE; } case EF_TELE_PHASE: { teleport_player(10); *ident = TRUE; return TRUE; } case EF_TELE_LONG: { teleport_player(100); *ident = TRUE; return TRUE; } case EF_TELE_LEVEL: { (void)teleport_player_level(); *ident = TRUE; return TRUE; } case EF_CONFUSING: { if (p_ptr->confusing == 0) { msg("Your hands begin to glow."); p_ptr->confusing = TRUE; *ident = TRUE; } return TRUE; } case EF_MAPPING: { map_area(); *ident = TRUE; return TRUE; } case EF_RUNE: { warding_glyph(); *ident = TRUE; return TRUE; } case EF_ACQUIRE: { acquirement(py, px, p_ptr->depth, 1, TRUE); *ident = TRUE; return TRUE; } case EF_ACQUIRE2: { acquirement(py, px, p_ptr->depth, randint1(2) + 1, TRUE); *ident = TRUE; return TRUE; } case EF_ANNOY_MON: { msg("There is a high pitched humming noise."); aggravate_monsters(0); *ident = TRUE; return TRUE; } case EF_CREATE_TRAP: { /* Hack -- no traps in the town */ if (p_ptr->depth == 0) return TRUE; trap_creation(); msg("You hear a low-pitched whistling sound."); *ident = TRUE; return TRUE; } case EF_DESTROY_TDOORS: { if (destroy_doors_touch()) *ident = TRUE; return TRUE; } case EF_RECHARGE: { *ident = TRUE; if (!recharge(60)) return FALSE; return TRUE; } case EF_BANISHMENT: { *ident = TRUE; if (!banishment()) return FALSE; return TRUE; } case EF_DARKNESS: { if (!check_state(OF_RES_DARK, p_ptr->state.flags)) (void)inc_timed(TMD_BLIND, 3 + randint1(5), TRUE, TRUE); unlight_area(10, 3); wieldeds_notice_flag(OF_RES_DARK); *ident = TRUE; return TRUE; } case EF_PROTEVIL: { if (inc_timed(TMD_PROTEVIL, randint1(25) + 3 * p_ptr->lev, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_SATISFY: { if (set_food(PY_FOOD_MAX - 1)) *ident = TRUE; return TRUE; } case EF_CURSE_WEAPON: { if (curse_weapon()) *ident = TRUE; return TRUE; } case EF_CURSE_ARMOR: { if (curse_armor()) *ident = TRUE; return TRUE; } case EF_BLESSING: { if (inc_timed(TMD_BLESSED, randint1(12) + 6, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_BLESSING2: { if (inc_timed(TMD_BLESSED, randint1(24) + 12, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_BLESSING3: { if (inc_timed(TMD_BLESSED, randint1(48) + 24, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RECALL: { set_recall(); *ident = TRUE; return TRUE; } case EF_DEEP_DESCENT: { int i, target_depth = p_ptr->depth; /* Calculate target depth */ for (i = 2; i > 0; i--) { if (is_quest(target_depth)) break; if (target_depth >= MAX_DEPTH - 1) break; target_depth++; } if (target_depth > p_ptr->depth) { msgt(MSG_TPLEVEL, "You sink through the floor..."); dungeon_change_level(target_depth); *ident = TRUE; return TRUE; } else { msgt(MSG_TPLEVEL, "You sense a malevolent presence blocking passage to the levels below."); *ident = TRUE; return FALSE; } } case EF_LOSHASTE: { if (speed_monsters()) *ident = TRUE; return TRUE; } case EF_LOSSLEEP: { if (sleep_monsters(aware)) *ident = TRUE; return TRUE; } case EF_LOSSLOW: { if (slow_monsters()) *ident = TRUE; return TRUE; } case EF_LOSCONF: { if (confuse_monsters(aware)) *ident = TRUE; return TRUE; } case EF_LOSKILL: { (void)mass_banishment(); *ident = TRUE; return TRUE; } case EF_EARTHQUAKES: { earthquake(py, px, 10); *ident = TRUE; return TRUE; } case EF_DESTRUCTION2: { destroy_area(py, px, 15, TRUE); *ident = TRUE; return TRUE; } case EF_ILLUMINATION: { if (light_area(damroll(2, 15), 3)) *ident = TRUE; return TRUE; } case EF_CLAIRVOYANCE: { *ident = TRUE; wiz_light(); (void)detect_traps(TRUE); (void)detect_doorstairs(TRUE); return TRUE; } case EF_PROBING: { *ident = probing(); return TRUE; } case EF_STONE_TO_MUD: { if (wall_to_mud(dir)) *ident = TRUE; return TRUE; } case EF_CONFUSE2: { *ident = TRUE; confuse_monster(dir, 20, aware); return TRUE; } case EF_BIZARRE: { *ident = TRUE; ring_of_power(dir); return TRUE; } case EF_STAR_BALL: { int i; *ident = TRUE; for (i = 0; i < 8; i++) fire_ball(GF_ELEC, ddd[i], (150 * (100 + boost) / 100), 3); return TRUE; } case EF_RAGE_BLESS_RESIST: { dur = randint1(50) + 50; *ident = TRUE; (void)hp_player(30); (void)clear_timed(TMD_AFRAID, TRUE); (void)inc_timed(TMD_BOLD, dur, TRUE, TRUE); (void)inc_timed(TMD_SHERO, dur, TRUE, TRUE); (void)inc_timed(TMD_BLESSED, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_ACID, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_ELEC, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_FIRE, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_COLD, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_POIS, randint1(50) + 50, TRUE, TRUE); return TRUE; } case EF_SLEEPII: { *ident = TRUE; sleep_monsters_touch(aware); return TRUE; } case EF_RESTORE_LIFE: { *ident = TRUE; restore_level(); return TRUE; } case EF_MISSILE: { *ident = TRUE; dam = damroll(3, 4) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_MISSILE, dir, dam); return TRUE; } case EF_DISPEL_EVIL: { *ident = TRUE; dam = p_ptr->lev * 5 * (100 + boost) / 100; dispel_evil(dam); return TRUE; } case EF_DISPEL_EVIL60: { dam = 60 * (100 + boost) / 100; if (dispel_evil(dam)) *ident = TRUE; return TRUE; } case EF_DISPEL_UNDEAD: { dam = 60 * (100 + boost) / 100; if (dispel_undead(dam)) *ident = TRUE; return TRUE; } case EF_DISPEL_ALL: { dam = 120 * (100 + boost) / 100; if (dispel_monsters(dam)) *ident = TRUE; return TRUE; } case EF_HASTE: { if (!p_ptr->timed[TMD_FAST]) { if (set_timed(TMD_FAST, damroll(2, 10) + 20, TRUE)) *ident = TRUE; } else { (void)inc_timed(TMD_FAST, 5, TRUE, TRUE); } return TRUE; } case EF_HASTE1: { if (!p_ptr->timed[TMD_FAST]) { if (set_timed(TMD_FAST, randint1(20) + 20, TRUE)) *ident = TRUE; } else { (void)inc_timed(TMD_FAST, 5, TRUE, TRUE); } return TRUE; } case EF_HASTE2: { if (!p_ptr->timed[TMD_FAST]) { if (set_timed(TMD_FAST, randint1(75) + 75, TRUE)) *ident = TRUE; } else { (void)inc_timed(TMD_FAST, 5, TRUE, TRUE); } return TRUE; } case EF_FIRE_BOLT: { *ident = TRUE; dam = damroll(9, 8) * (100 + boost) / 100; fire_bolt(GF_FIRE, dir, dam); return TRUE; } case EF_FIRE_BOLT2: { dam = damroll(12, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_FIRE, dir, dam); *ident = TRUE; return TRUE; } case EF_FIRE_BOLT3: { dam = damroll(16, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_FIRE, dir, dam); *ident = TRUE; return TRUE; } case EF_FIRE_BOLT72: { dam = 72 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 2); return TRUE; } case EF_FIRE_BALL: { dam = 144 * (100 + boost) / 100; fire_ball(GF_FIRE, dir, dam, 2); *ident = TRUE; return TRUE; } case EF_FIRE_BALL2: { dam = 120 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 3); return TRUE; } case EF_FIRE_BALL200: { dam = 200 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 3); return TRUE; } case EF_COLD_BOLT: { dam = damroll(6, 8) * (100 + boost) / 100; *ident = TRUE; fire_bolt_or_beam(beam, GF_COLD, dir, dam); return TRUE; } case EF_COLD_BOLT2: { dam = damroll(12, 8) * (100 + boost) / 100; *ident = TRUE; fire_bolt(GF_COLD, dir, dam); return TRUE; } case EF_COLD_BALL2: { dam = 200 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 3); return TRUE; } case EF_COLD_BALL50: { dam = 50 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 2); return TRUE; } case EF_COLD_BALL100: { dam = 100 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 2); return TRUE; } case EF_COLD_BALL160: { dam = 160 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 3); return TRUE; } case EF_ACID_BOLT: { dam = damroll(5, 8) * (100 + boost) / 100; *ident = TRUE; fire_bolt(GF_ACID, dir, dam); return TRUE; } case EF_ACID_BOLT2: { dam = damroll(10, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_ACID, dir, dam); *ident = TRUE; return TRUE; } case EF_ACID_BOLT3: { dam = damroll(12, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_ACID, dir, dam); *ident = TRUE; return TRUE; } case EF_ACID_BALL: { dam = 120 * (100 + boost) / 100; fire_ball(GF_ACID, dir, dam, 2); *ident = TRUE; return TRUE; } case EF_ELEC_BOLT: { dam = damroll(6, 6) * (100 + boost) / 100; *ident = TRUE; fire_beam(GF_ELEC, dir, dam); return TRUE; } case EF_ELEC_BALL: { dam = 64 * (100 + boost) / 100; fire_ball(GF_ELEC, dir, dam, 2); *ident = TRUE; return TRUE; } case EF_ELEC_BALL2: { dam = 250 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_ELEC, dir, dam, 3); return TRUE; } case EF_ARROW: { dam = 150 * (100 + boost) / 100; *ident = TRUE; fire_bolt(GF_ARROW, dir, dam); return TRUE; } case EF_REM_FEAR_POIS: { *ident = TRUE; (void)clear_timed(TMD_AFRAID, TRUE); (void)clear_timed(TMD_POISONED, TRUE); return TRUE; } case EF_STINKING_CLOUD: { dam = 12 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_POIS, dir, dam, 3); return TRUE; } case EF_DRAIN_LIFE1: { dam = 90 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_DRAIN_LIFE2: { dam = 120 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_DRAIN_LIFE3: { dam = 150 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_DRAIN_LIFE4: { dam = 250 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_FIREBRAND: { *ident = TRUE; if (!brand_bolts()) return FALSE; return TRUE; } case EF_MANA_BOLT: { dam = damroll(12, 8) * (100 + boost) / 100; fire_bolt(GF_MANA, dir, dam); *ident = TRUE; return TRUE; } case EF_MON_HEAL: { if (heal_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_HASTE: { if (speed_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_SLOW: { if (slow_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_CONFUSE: { if (confuse_monster(dir, 10, aware)) *ident = TRUE; return TRUE; } case EF_MON_SLEEP: { if (sleep_monster(dir, aware)) *ident = TRUE; return TRUE; } case EF_MON_CLONE: { if (clone_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_SCARE: { if (fear_monster(dir, 10, aware)) *ident = TRUE; return TRUE; } case EF_LIGHT_LINE: { msg("A line of shimmering blue light appears."); light_line(dir); *ident = TRUE; return TRUE; } case EF_TELE_OTHER: { if (teleport_monster(dir)) *ident = TRUE; return TRUE; } case EF_DISARMING: { if (disarm_trap(dir)) *ident = TRUE; return TRUE; } case EF_TDOOR_DEST: { if (destroy_door(dir)) *ident = TRUE; return TRUE; } case EF_POLYMORPH: { if (poly_monster(dir)) *ident = TRUE; return TRUE; } case EF_STARLIGHT: { int i; if (!p_ptr->timed[TMD_BLIND]) msg("Light shoots in all directions!"); for (i = 0; i < 8; i++) light_line(ddd[i]); *ident = TRUE; return TRUE; } case EF_STARLIGHT2: { int k; for (k = 0; k < 8; k++) strong_light_line(ddd[k]); *ident = TRUE; return TRUE; } case EF_BERSERKER: { dur = randint1(50) + 50; if (inc_timed(TMD_BOLD, dur, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_SHERO, dur, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_WONDER: { if (effect_wonder(dir, randint1(100) + p_ptr->lev / 5, beam)) *ident = TRUE; return TRUE; } case EF_WAND_BREATH: { /* table of random ball effects and their damages */ const int breath_types[] = { GF_ACID, 200, GF_ELEC, 160, GF_FIRE, 200, GF_COLD, 160, GF_POIS, 120 }; /* pick a random (type, damage) tuple in the table */ int which = 2 * randint0(sizeof(breath_types) / (2 * sizeof(int))); fire_ball(breath_types[which], dir, breath_types[which + 1], 3); *ident = TRUE; return TRUE; } case EF_STAFF_MAGI: { if (do_res_stat(A_INT)) *ident = TRUE; if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; *ident = TRUE; msg("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); } return TRUE; } case EF_STAFF_HOLY: { dam = 120 * (100 + boost) / 100; if (dispel_evil(dam)) *ident = TRUE; if (inc_timed(TMD_PROTEVIL, randint1(25) + 3 * p_ptr->lev, TRUE, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (hp_player(50)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_DRINK_BREATH: { const int breath_types[] = { GF_FIRE, 80, GF_COLD, 80, }; int which = 2 * randint0(N_ELEMENTS(breath_types) / 2); fire_ball(breath_types[which], dir, breath_types[which + 1], 2); *ident = TRUE; return TRUE; } case EF_DRINK_GOOD: { msg("You feel less thirsty."); *ident = TRUE; return TRUE; } case EF_DRINK_DEATH: { msg("A feeling of Death flows through your body."); take_hit(5000, "a potion of Death"); *ident = TRUE; return TRUE; } case EF_DRINK_RUIN: { msg("Your nerves and muscles feel weak and lifeless!"); take_hit(damroll(10, 10), "a potion of Ruination"); player_stat_dec(p_ptr, A_DEX, TRUE); player_stat_dec(p_ptr, A_WIS, TRUE); player_stat_dec(p_ptr, A_CON, TRUE); player_stat_dec(p_ptr, A_STR, TRUE); player_stat_dec(p_ptr, A_CHR, TRUE); player_stat_dec(p_ptr, A_INT, TRUE); *ident = TRUE; return TRUE; } case EF_DRINK_DETONATE: { msg("Massive explosions rupture your body!"); take_hit(damroll(50, 20), "a potion of Detonation"); (void)inc_timed(TMD_STUN, 75, TRUE, TRUE); (void)inc_timed(TMD_CUT, 5000, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_DRINK_SALT: { msg("The potion makes you vomit!"); (void)set_food(PY_FOOD_STARVE - 1); (void)clear_timed(TMD_POISONED, TRUE); (void)inc_timed(TMD_PARALYZED, 4, TRUE, FALSE); *ident = TRUE; return TRUE; } case EF_FOOD_GOOD: { msg("That tastes good."); *ident = TRUE; return TRUE; } case EF_FOOD_WAYBREAD: { msg("That tastes good."); (void)clear_timed(TMD_POISONED, TRUE); (void)hp_player(damroll(4, 8)); *ident = TRUE; return TRUE; } case EF_SHROOM_EMERGENCY: { (void)set_timed(TMD_IMAGE, rand_spread(250, 50), TRUE); (void)set_timed(TMD_OPP_FIRE, rand_spread(30, 10), TRUE); (void)set_timed(TMD_OPP_COLD, rand_spread(30, 10), TRUE); (void)hp_player(200); *ident = TRUE; return TRUE; } case EF_SHROOM_TERROR: { if (set_timed(TMD_TERROR, rand_spread(100, 20), TRUE)) *ident = TRUE; return TRUE; } case EF_SHROOM_STONE: { if (set_timed(TMD_STONESKIN, rand_spread(80, 20), TRUE)) *ident = TRUE; return TRUE; } case EF_SHROOM_DEBILITY: { int stat = one_in_(2) ? A_STR : A_CON; if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; msg("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); *ident = TRUE; } (void)do_dec_stat(stat, FALSE); *ident = TRUE; return TRUE; } case EF_SHROOM_SPRINTING: { if (inc_timed(TMD_SPRINT, 100, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_SHROOM_PURGING: { (void)set_food(PY_FOOD_FAINT - 1); if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; return TRUE; } case EF_RING_ACID: { dam = 70 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_ACID, dir, dam, 2); inc_timed(TMD_OPP_ACID, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_RING_FLAMES: { dam = 80 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 2); inc_timed(TMD_OPP_FIRE, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_RING_ICE: { dam = 75 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 2); inc_timed(TMD_OPP_COLD, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_RING_LIGHTNING: { dam = 85 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_ELEC, dir, dam, 2); inc_timed(TMD_OPP_ELEC, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_DRAGON_BLUE: { dam = 100 * (100 + boost) / 100; msgt(MSG_BR_ELEC, "You breathe lightning."); fire_ball(GF_ELEC, dir, dam, 2); return TRUE; } case EF_DRAGON_GREEN: { dam = 150 * (100 + boost) / 100; msgt(MSG_BR_GAS, "You breathe poison gas."); fire_ball(GF_POIS, dir, dam, 2); return TRUE; } case EF_DRAGON_RED: { dam = 200 * (100 + boost) / 100; msgt(MSG_BR_FIRE, "You breathe fire."); fire_ball(GF_FIRE, dir, dam, 2); return TRUE; } case EF_DRAGON_MULTIHUED: { static const struct { int msg_sound; const char *msg; int typ; } mh[] = { { MSG_BR_ELEC, "lightning", GF_ELEC }, { MSG_BR_FROST, "frost", GF_COLD }, { MSG_BR_ACID, "acid", GF_ACID }, { MSG_BR_GAS, "poison gas", GF_POIS }, { MSG_BR_FIRE, "fire", GF_FIRE } }; int chance = randint0(5); dam = 250 * (100 + boost) / 100; msgt(mh[chance].msg_sound, "You breathe %s.", mh[chance].msg); fire_ball(mh[chance].typ, dir, dam, 2); return TRUE; } case EF_DRAGON_BRONZE: { dam = 120 * (100 + boost) / 100; msgt(MSG_BR_CONF, "You breathe confusion."); fire_ball(GF_CONFU, dir, dam, 2); return TRUE; } case EF_DRAGON_GOLD: { dam = 130 * (100 + boost) / 100; msgt(MSG_BR_SOUND, "You breathe sound."); fire_ball(GF_SOUND, dir, dam, 2); return TRUE; } case EF_DRAGON_CHAOS: { dam = 220 * (100 + boost) / 100; chance = randint0(2); msgt((chance == 1 ? MSG_BR_CHAOS : MSG_BR_DISEN), "You breathe %s.", ((chance == 1 ? "chaos" : "disenchantment"))); fire_ball((chance == 1 ? GF_CHAOS : GF_DISEN), dir, dam, 2); return TRUE; } case EF_DRAGON_LAW: { dam = 230 * (100 + boost) / 100; chance = randint0(2); msgt((chance == 1 ? MSG_BR_SOUND : MSG_BR_SHARDS), "You breathe %s.", ((chance == 1 ? "sound" : "shards"))); fire_ball((chance == 1 ? GF_SOUND : GF_SHARD), dir, dam, 2); return TRUE; } case EF_DRAGON_BALANCE: { dam = 250 * (100 + boost) / 100; chance = randint0(4); msg("You breathe %s.", ((chance == 1) ? "chaos" : ((chance == 2) ? "disenchantment" : ((chance == 3) ? "sound" : "shards")))); fire_ball(((chance == 1) ? GF_CHAOS : ((chance == 2) ? GF_DISEN : ((chance == 3) ? GF_SOUND : GF_SHARD))), dir, dam, 2); return TRUE; } case EF_DRAGON_SHINING: { dam = 200 * (100 + boost) / 100; chance = randint0(2); msgt((chance == 0 ? MSG_BR_LIGHT : MSG_BR_DARK), "You breathe %s.", ((chance == 0 ? "light" : "darkness"))); fire_ball((chance == 0 ? GF_LIGHT : GF_DARK), dir, dam, 2); return TRUE; } case EF_DRAGON_POWER: { dam = 300 * (100 + boost) / 100; msgt(MSG_BR_ELEMENTS, "You breathe the elements."); fire_ball(GF_MISSILE, dir, dam, 2); return TRUE; } case EF_TRAP_DOOR: { msg("You fall through a trap door!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently down to the next level."); } else { take_hit(damroll(2, 8), "a trap"); } wieldeds_notice_flag(OF_FEATHER); dungeon_change_level(p_ptr->depth + 1); return TRUE; } case EF_TRAP_PIT: { msg("You fall into a pit!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently to the bottom of the pit."); } else { take_hit(damroll(2, 6), "a trap"); } wieldeds_notice_flag(OF_FEATHER); return TRUE; } case EF_TRAP_PIT_SPIKES: { msg("You fall into a spiked pit!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently to the floor of the pit."); msg("You carefully avoid touching the spikes."); } else { int dam = damroll(2, 6); /* Extra spike damage */ if (one_in_(2)) { msg("You are impaled!"); dam *= 2; (void)inc_timed(TMD_CUT, randint1(dam), TRUE, TRUE); } take_hit(dam, "a trap"); } wieldeds_notice_flag(OF_FEATHER); return TRUE; } case EF_TRAP_PIT_POISON: { msg("You fall into a spiked pit!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently to the floor of the pit."); msg("You carefully avoid touching the spikes."); } else { int dam = damroll(2, 6); /* Extra spike damage */ if (one_in_(2)) { msg("You are impaled on poisonous spikes!"); (void)inc_timed(TMD_CUT, randint1(dam * 2), TRUE, TRUE); (void)inc_timed(TMD_POISONED, randint1(dam * 4), TRUE, TRUE); } take_hit(dam, "a trap"); } wieldeds_notice_flag(OF_FEATHER); return TRUE; } case EF_TRAP_RUNE_SUMMON: { int i; int num = 2 + randint1(3); msgt(MSG_SUM_MONSTER, "You are enveloped in a cloud of smoke!"); /* Remove trap */ cave->info[py][px] &= ~(CAVE_MARK); cave_set_feat(cave, py, px, FEAT_FLOOR); for (i = 0; i < num; i++) (void)summon_specific(py, px, p_ptr->depth, 0, 1); break; } case EF_TRAP_RUNE_TELEPORT: { msg("You hit a teleport trap!"); teleport_player(100); return TRUE; } case EF_TRAP_SPOT_FIRE: { int dam; msg("You are enveloped in flames!"); dam = damroll(4, 6); dam = adjust_dam(GF_FIRE, dam, RANDOMISE, check_for_resist(GF_FIRE, p_ptr->state.flags, TRUE)); if (dam) { take_hit(dam, "a fire trap"); inven_damage(GF_FIRE, MIN(dam * 5, 300)); } return TRUE; } case EF_TRAP_SPOT_ACID: { int dam; msg("You are splashed with acid!"); dam = damroll(4, 6); dam = adjust_dam(GF_ACID, dam, RANDOMISE, check_for_resist(GF_ACID, p_ptr->state.flags, TRUE)); if (dam) { take_hit(dam, "an acid trap"); inven_damage(GF_ACID, MIN(dam * 5, 300)); } return TRUE; } case EF_TRAP_DART_SLOW: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)inc_timed(TMD_SLOW, randint0(20) + 20, TRUE, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_DART_LOSE_STR: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)do_dec_stat(A_STR, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_DART_LOSE_DEX: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)do_dec_stat(A_DEX, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_DART_LOSE_CON: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)do_dec_stat(A_CON, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_GAS_BLIND: { msg("You are surrounded by a black gas!"); (void)inc_timed(TMD_BLIND, randint0(50) + 25, TRUE, TRUE); return TRUE; } case EF_TRAP_GAS_CONFUSE: { msg("You are surrounded by a gas of scintillating colors!"); (void)inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE, TRUE); return TRUE; } case EF_TRAP_GAS_POISON: { msg("You are surrounded by a pungent green gas!"); (void)inc_timed(TMD_POISONED, randint0(20) + 10, TRUE, TRUE); return TRUE; } case EF_TRAP_GAS_SLEEP: { msg("You are surrounded by a strange white mist!"); (void)inc_timed(TMD_PARALYZED, randint0(10) + 5, TRUE, TRUE); return TRUE; } case EF_XXX: case EF_MAX: break; } /* Not used */ msg("Effect not handled."); return FALSE; }
static void _shatter_device_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Shatter Device"); break; case SPELL_DESC: var_set_string(res, "Destroy a magical device in your inventory for various effects."); break; case SPELL_CAST: { obj_prompt_t prompt = {0}; var_set_bool(res, FALSE); prompt.prompt = "Shatter which device?"; prompt.error = "You have nothing to shatter."; prompt.filter = object_is_device; prompt.where[0] = INV_PACK; prompt.where[1] = INV_FLOOR; obj_prompt(&prompt); if (!prompt.obj) return; var_set_bool(res, TRUE); if (prompt.obj->activation.type == EFFECT_NONE) { msg_print("Nothing happens."); } else if (prompt.obj->activation.type == EFFECT_DESTRUCTION) { if (destroy_area(py, px, 15 + p_ptr->lev + randint0(11), 4 * p_ptr->lev)) msg_print("The dungeon collapses..."); else msg_print("The dungeon trembles."); } else if ( prompt.obj->activation.type == EFFECT_HEAL_CURING || prompt.obj->activation.type == EFFECT_HEAL_CURING_HERO || prompt.obj->activation.type == EFFECT_RESTORING ) { msg_print("You feel life flow through your body!"); restore_level(); (void)set_poisoned(0, TRUE); (void)set_blind(0, TRUE); (void)set_confused(0, TRUE); (void)set_image(0, TRUE); (void)set_stun(0, TRUE); (void)set_cut(0, TRUE); (void)do_res_stat(A_STR); (void)do_res_stat(A_CON); (void)do_res_stat(A_DEX); (void)do_res_stat(A_WIS); (void)do_res_stat(A_INT); (void)do_res_stat(A_CHR); update_stuff(); /* hp may change if Con was drained ... */ hp_player(5000); } else if ( prompt.obj->activation.type == EFFECT_TELEPORT_AWAY || prompt.obj->activation.type == EFFECT_BANISH_EVIL || prompt.obj->activation.type == EFFECT_BANISH_ALL ) { banish_monsters(p_ptr->lev * 4); } else { project(0, 5, py, px, prompt.obj->activation.difficulty * 16, _object_dam_type(prompt.obj), PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL, -1); } prompt.obj->number--; obj_release(prompt.obj, 0); break; } default: default_spell(cmd, res); break; } }
/** * Add an item to the players inventory. * * If the new item can combine with an existing item in the inventory, * it will do so, using object_similar() and object_absorb(), else, * the item will be placed into the first available gear array index. * * This function can be used to "over-fill" the player's pack, but only * once, and such an action must trigger the "overflow" code immediately. * Note that when the pack is being "over-filled", the new item must be * placed into the "overflow" slot, and the "overflow" must take place * before the pack is reordered, but (optionally) after the pack is * combined. This may be tricky. See "dungeon.c" for info. * * Note that this code removes any location information from the object once * it is placed into the inventory, but takes no responsibility for removing * the object from any other pile it was in. */ void inven_carry(struct player *p, struct object *obj, bool absorb, bool message) { bool combining = false; /* Check for combining, if appropriate */ if (absorb) { struct object *combine_item = NULL; struct object *gear_obj = p->gear; while (combine_item == false && gear_obj) { if (!object_is_equipped(p->body, gear_obj) && object_similar(gear_obj, obj, OSTACK_PACK)) { combine_item = gear_obj; } gear_obj = gear_obj->next; } if (combine_item) { /* Increase the weight */ p->upkeep->total_weight += (obj->number * obj->weight); /* Combine the items, and their known versions */ object_absorb(combine_item->known, obj->known); obj->known = NULL; object_absorb(combine_item, obj); obj = combine_item; combining = true; } } /* We didn't manage the find an object to combine with */ if (!combining) { /* Paranoia */ assert(pack_slots_used(p) <= z_info->pack_size); gear_insert_end(obj); apply_autoinscription(obj); /* Remove cave object details */ obj->held_m_idx = 0; obj->grid = loc(0, 0); obj->known->grid = loc(0, 0); /* Update the inventory */ p->upkeep->total_weight += (obj->number * obj->weight); p->upkeep->notice |= (PN_COMBINE); /* Hobbits ID mushrooms on pickup, gnomes ID wands and staffs on pickup */ if (!object_flavor_is_aware(obj)) { if (player_has(player, PF_KNOW_MUSHROOM) && tval_is_mushroom(obj)) { object_flavor_aware(obj); msg("Mushrooms for breakfast!"); } else if (player_has(player, PF_KNOW_ZAPPER) && tval_is_zapper(obj)) object_flavor_aware(obj); } } p->upkeep->update |= (PU_BONUS | PU_INVEN); p->upkeep->redraw |= (PR_INVEN); update_stuff(player); if (message) { char o_name[80]; object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); msg("You have %s (%c).", o_name, gear_to_label(obj)); } if (object_is_in_quiver(p, obj)) sound(MSG_QUIVER); }
static bool quaff_potion(object_type *o_ptr, bool *ident) { /* Analyze the potion */ switch (o_ptr->sval) { case SV_POTION_WATER: case SV_POTION_APPLE_JUICE: case SV_POTION_SLIME_MOLD: { msg_print("You feel less thirsty."); *ident = TRUE; break; } case SV_POTION_SLOWNESS: { if (set_slow(p_ptr->slow + randint(25) + 15)) *ident = TRUE; break; } case SV_POTION_SALT_WATER: { msg_print("The potion makes you vomit!"); (void)set_food(PY_FOOD_STARVE - 1); (void)set_poisoned(0); (void)set_paralyzed(p_ptr->paralyzed + 4); *ident = TRUE; break; } case SV_POTION_POISON: { if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { if (set_poisoned(p_ptr->poisoned + rand_int(15) + 10)) { *ident = TRUE; } } break; } case SV_POTION_BLINDNESS: { if (!p_ptr->resist_blind) { if (set_blind(p_ptr->blind + rand_int(100) + 100)) { *ident = TRUE; } } break; } case SV_POTION_CONFUSION: { if (!p_ptr->resist_confu) { if (set_confused(p_ptr->confused + rand_int(20) + 15)) { *ident = TRUE; } } break; } case SV_POTION_SLEEP: { if (!p_ptr->free_act) { if (set_paralyzed(p_ptr->paralyzed + rand_int(4) + 4)) { *ident = TRUE; } } break; } case SV_POTION_LOSE_MEMORIES: { if (!p_ptr->hold_life && (p_ptr->exp > 0)) { msg_print("You feel your memories fade."); lose_exp(p_ptr->exp / 4); *ident = TRUE; } break; } case SV_POTION_RUINATION: { msg_print("Your nerves and muscles feel weak and lifeless!"); take_hit(damroll(10, 10), "a potion of Ruination"); (void)dec_stat(A_DEX, 25, TRUE); (void)dec_stat(A_WIS, 25, TRUE); (void)dec_stat(A_CON, 25, TRUE); (void)dec_stat(A_STR, 25, TRUE); (void)dec_stat(A_CHR, 25, TRUE); (void)dec_stat(A_INT, 25, TRUE); *ident = TRUE; break; } case SV_POTION_DEC_STR: { if (do_dec_stat(A_STR)) *ident = TRUE; break; } case SV_POTION_DEC_INT: { if (do_dec_stat(A_INT)) *ident = TRUE; break; } case SV_POTION_DEC_WIS: { if (do_dec_stat(A_WIS)) *ident = TRUE; break; } case SV_POTION_DEC_DEX: { if (do_dec_stat(A_DEX)) *ident = TRUE; break; } case SV_POTION_DEC_CON: { if (do_dec_stat(A_CON)) *ident = TRUE; break; } case SV_POTION_DEC_CHR: { if (do_dec_stat(A_CHR)) *ident = TRUE; break; } case SV_POTION_DETONATIONS: { msg_print("Massive explosions rupture your body!"); take_hit(damroll(50, 20), "a potion of Detonation"); (void)set_stun(p_ptr->stun + 75); (void)set_cut(p_ptr->cut + 5000); *ident = TRUE; break; } case SV_POTION_DEATH: { msg_print("A feeling of Death flows through your body."); take_hit(5000, "a potion of Death"); *ident = TRUE; break; } case SV_POTION_INFRAVISION: { if (set_tim_infra(p_ptr->tim_infra + 100 + randint(100))) { *ident = TRUE; } break; } case SV_POTION_DETECT_INVIS: { if (set_tim_invis(p_ptr->tim_invis + 12 + randint(12))) { *ident = TRUE; } break; } case SV_POTION_SLOW_POISON: { if (set_poisoned(p_ptr->poisoned / 2)) *ident = TRUE; break; } case SV_POTION_CURE_POISON: { if (set_poisoned(0)) *ident = TRUE; break; } case SV_POTION_BOLDNESS: { if (set_afraid(0)) *ident = TRUE; break; } case SV_POTION_SPEED: { if (!p_ptr->fast) { if (set_fast(randint(25) + 15)) *ident = TRUE; } else { (void)set_fast(p_ptr->fast + 5); } break; } case SV_POTION_RESIST_HEAT: { if (set_oppose_fire(p_ptr->oppose_fire + randint(10) + 10)) { *ident = TRUE; } break; } case SV_POTION_RESIST_COLD: { if (set_oppose_cold(p_ptr->oppose_cold + randint(10) + 10)) { *ident = TRUE; } break; } case SV_POTION_HEROISM: { if (hp_player(10)) *ident = TRUE; if (set_afraid(0)) *ident = TRUE; if (set_hero(p_ptr->hero + randint(25) + 25)) *ident = TRUE; break; } case SV_POTION_BERSERK_STRENGTH: { if (hp_player(30)) *ident = TRUE; if (set_afraid(0)) *ident = TRUE; if (set_shero(p_ptr->shero + randint(25) + 25)) *ident = TRUE; break; } case SV_POTION_CURE_LIGHT: { if (hp_player(damroll(2, 8))) *ident = TRUE; if (set_blind(0)) *ident = TRUE; if (set_cut(p_ptr->cut - 10)) *ident = TRUE; break; } case SV_POTION_CURE_SERIOUS: { if (hp_player(damroll(4, 8))) *ident = TRUE; if (set_blind(0)) *ident = TRUE; if (set_confused(0)) *ident = TRUE; if (set_cut((p_ptr->cut / 2) - 50)) *ident = TRUE; break; } case SV_POTION_CURE_CRITICAL: { if (hp_player(damroll(6, 8))) *ident = TRUE; if (set_blind(0)) *ident = TRUE; if (set_confused(0)) *ident = TRUE; if (set_poisoned(0)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; break; } case SV_POTION_HEALING: { if (hp_player(300)) *ident = TRUE; if (set_blind(0)) *ident = TRUE; if (set_confused(0)) *ident = TRUE; if (set_poisoned(0)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; break; } case SV_POTION_STAR_HEALING: { if (hp_player(1200)) *ident = TRUE; if (set_blind(0)) *ident = TRUE; if (set_confused(0)) *ident = TRUE; if (set_poisoned(0)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; break; } case SV_POTION_LIFE: { msg_print("You feel life flow through your body!"); restore_level(); (void)set_poisoned(0); (void)set_blind(0); (void)set_confused(0); (void)set_image(0); (void)set_stun(0); (void)set_cut(0); (void)do_res_stat(A_STR); (void)do_res_stat(A_CON); (void)do_res_stat(A_DEX); (void)do_res_stat(A_WIS); (void)do_res_stat(A_INT); (void)do_res_stat(A_CHR); /* Recalculate max. hitpoints */ update_stuff(); hp_player(5000); *ident = TRUE; break; } case SV_POTION_RESTORE_MANA: { if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; msg_print("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); *ident = TRUE; } break; } case SV_POTION_RESTORE_EXP: { if (restore_level()) *ident = TRUE; break; } case SV_POTION_RES_STR: { if (do_res_stat(A_STR)) *ident = TRUE; break; } case SV_POTION_RES_INT: { if (do_res_stat(A_INT)) *ident = TRUE; break; } case SV_POTION_RES_WIS: { if (do_res_stat(A_WIS)) *ident = TRUE; break; } case SV_POTION_RES_DEX: { if (do_res_stat(A_DEX)) *ident = TRUE; break; } case SV_POTION_RES_CON: { if (do_res_stat(A_CON)) *ident = TRUE; break; } case SV_POTION_RES_CHR: { if (do_res_stat(A_CHR)) *ident = TRUE; break; } case SV_POTION_INC_STR: { if (do_inc_stat(A_STR)) *ident = TRUE; break; } case SV_POTION_INC_INT: { if (do_inc_stat(A_INT)) *ident = TRUE; break; } case SV_POTION_INC_WIS: { if (do_inc_stat(A_WIS)) *ident = TRUE; break; } case SV_POTION_INC_DEX: { if (do_inc_stat(A_DEX)) *ident = TRUE; break; } case SV_POTION_INC_CON: { if (do_inc_stat(A_CON)) *ident = TRUE; break; } case SV_POTION_INC_CHR: { if (do_inc_stat(A_CHR)) *ident = TRUE; break; } case SV_POTION_AUGMENTATION: { if (do_inc_stat(A_STR)) *ident = TRUE; if (do_inc_stat(A_INT)) *ident = TRUE; if (do_inc_stat(A_WIS)) *ident = TRUE; if (do_inc_stat(A_DEX)) *ident = TRUE; if (do_inc_stat(A_CON)) *ident = TRUE; if (do_inc_stat(A_CHR)) *ident = TRUE; break; } case SV_POTION_ENLIGHTENMENT: { msg_print("An image of your surroundings forms in your mind..."); wiz_lite(); *ident = TRUE; break; } case SV_POTION_STAR_ENLIGHTENMENT: { msg_print("You begin to feel more enlightened..."); message_flush(); wiz_lite(); (void)do_inc_stat(A_INT); (void)do_inc_stat(A_WIS); (void)detect_traps(); (void)detect_doors(); (void)detect_stairs(); (void)detect_treasure(); (void)detect_objects_gold(); (void)detect_objects_normal(); identify_pack(); self_knowledge(); *ident = TRUE; break; } case SV_POTION_SELF_KNOWLEDGE: { msg_print("You begin to know yourself a little better..."); message_flush(); self_knowledge(); *ident = TRUE; break; } case SV_POTION_EXPERIENCE: { if (p_ptr->exp < PY_MAX_EXP) { s32b ee = (p_ptr->exp / 2) + 10; if (ee > 100000L) ee = 100000L; msg_print("You feel more experienced."); gain_exp(ee); *ident = TRUE; } break; } } return (TRUE); }
/* * Helper function for 'player_birth()'. * * This function handles "point-based" character creation. * * The player selects, for each stat, a value from 6 to 18 (inclusive), * each costing a certain amount of points (as above), from a pool of 30 * available points, to which race/house modifiers are then applied. * * Each unused point is converted into 100 experience points. */ static bool player_birth_aux_2(void) { int i; int row = 2; int col = 42; int stat = 0; int stats[A_MAX]; int cost; char ch; char buf[80]; /* Initialize stats */ for (i = 0; i < A_MAX; i++) { /* Initial stats */ stats[i] = p_ptr->stat_base[i]; } /* Determine experience and things */ get_extra(); /* Interact */ while (1) { /* Reset cost */ cost = 0; /* Process stats */ for (i = 0; i < A_MAX; i++) { /* Obtain a "bonus" for "race" */ int bonus = rp_ptr->r_adj[i] + hp_ptr->h_adj[i]; /* Apply the racial bonuses */ p_ptr->stat_base[i] = stats[i] + bonus; p_ptr->stat_drain[i] = 0; /* Total cost */ cost += birth_stat_costs[stats[i] + 4]; } /* Restrict cost */ if (cost > MAX_COST) { /* Warning */ bell("Excessive stats!"); /* Reduce stat */ stats[stat]--; /* Recompute costs */ continue; } p_ptr->new_exp = p_ptr->exp = PY_START_EXP; /* Calculate the bonuses and hitpoints */ p_ptr->update |= (PU_BONUS | PU_HP); /* Update stuff */ update_stuff(); /* Fully healed */ p_ptr->chp = p_ptr->mhp; /* Fully rested */ calc_voice(); p_ptr->csp = p_ptr->msp; /* Display the player */ display_player(0); /* Display the costs header */ c_put_str(TERM_WHITE, "Points Left:", 0, col + 21); strnfmt(buf, sizeof(buf), "%2d", MAX_COST - cost); c_put_str(TERM_L_GREEN, buf, 0, col + 34); /* Display the costs */ for (i = 0; i < A_MAX; i++) { byte attr = (i == stat) ? TERM_L_BLUE : TERM_L_WHITE; /* Display cost */ strnfmt(buf, sizeof(buf), "%4d", birth_stat_costs[stats[i] + 4]); c_put_str(attr, buf, row + i, col + 32); } /* Prompt */ Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, -1, TERM_SLATE, "Arrow keys allocate points to stats"); Term_putstr(QUESTION_COL, INSTRUCT_ROW + 2, -1, TERM_SLATE, " Enter accept current values"); /* Hack - highlight the key names */ Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, - 1, TERM_L_WHITE, "Arrow keys"); Term_putstr(QUESTION_COL + 5, INSTRUCT_ROW + 2, - 1, TERM_L_WHITE, "Enter"); /* Get key */ hide_cursor = TRUE; ch = inkey(); hide_cursor = FALSE; /* Quit */ if ((ch == 'Q') || (ch == 'q')) quit(NULL); /* Start over */ if (ch == ESCAPE) return (FALSE); /* Done */ if ((ch == '\r') || (ch == '\n')) break; /* Prev stat */ if (ch == '8') { stat = (stat + A_MAX - 1) % A_MAX; } /* Next stat */ if (ch == '2') { stat = (stat + 1) % A_MAX; } /* Decrease stat */ if ((ch == '4') && (stats[stat] > 0)) { stats[stat]--; } /* Increase stat */ if (ch == '6') { stats[stat]++; } } /* Done */ return (TRUE); }
/* * Increase your skills by spending experience points */ extern bool gain_skills(void) { int i; int row = 7; int col = 42; int skill = 0; int old_base[S_MAX]; int skill_gain[S_MAX]; int old_new_exp = p_ptr->new_exp; int total_cost = 0; //int old_csp = p_ptr->csp; //int old_msp = p_ptr->msp; char ch; char buf[80]; bool accepted; int tab = 0; // hack global variable skill_gain_in_progress = TRUE; /* save the old skills */ for (i = 0; i < S_MAX; i++) old_base[i] = p_ptr->skill_base[i]; /* initialise the skill gains */ for (i = 0; i < S_MAX; i++) skill_gain[i] = 0; /* Interact */ while (1) { // reset the total cost total_cost = 0; /* Process skills */ for (i = 0; i < S_MAX; i++) { /* Total cost */ total_cost += skill_cost(old_base[i], skill_gain[i]); } // set the new experience pool total p_ptr->new_exp = old_new_exp - total_cost; /* Restrict cost */ if (p_ptr->new_exp < 0) { /* Warning */ bell("Excessive skills!"); /* Reduce stat */ skill_gain[skill]--; /* Recompute costs */ continue; } /* Calculate the bonuses */ p_ptr->update |= (PU_BONUS); /* Set the redraw flag for everything */ p_ptr->redraw |= (PR_EXP | PR_BASIC); /* update the skills */ for (i = 0; i < S_MAX; i++) { p_ptr->skill_base[i] = old_base[i] + skill_gain[i]; } /* Update stuff */ update_stuff(); /* Update voice level */ //if (p_ptr->msp == 0) p_ptr->csp = 0; //else p_ptr->csp = (old_csp * p_ptr->msp) / old_msp; /* Display the player */ display_player(0); /* Display the costs header */ if (!character_dungeon) { if (p_ptr->new_exp >= 10000) tab = 0; else if (p_ptr->new_exp >= 1000) tab = 1; else if (p_ptr->new_exp >= 100) tab = 2; else if (p_ptr->new_exp >= 10) tab = 3; else tab = 4; strnfmt(buf, sizeof(buf), "%6d", p_ptr->new_exp); c_put_str(TERM_L_GREEN, buf, row - 2, col + 30); c_put_str(TERM_WHITE, "Points Left:", row - 2, col + 17 + tab); } /* Display the costs */ for (i = 0; i < S_MAX; i++) { byte attr = (i == skill) ? TERM_L_BLUE : TERM_L_WHITE; /* Display cost */ strnfmt(buf, sizeof(buf), "%6d", skill_cost(old_base[i], skill_gain[i])); c_put_str(attr, buf, row + i, col + 30); } /* Special Prompt? */ if (character_dungeon) { Term_putstr(QUESTION_COL + 38 + 2, INSTRUCT_ROW + 1, -1, TERM_SLATE, "ESC abort skill increases "); /* Hack - highlight the key names */ Term_putstr(QUESTION_COL + 38 + 2, INSTRUCT_ROW + 1, - 1, TERM_L_WHITE, "ESC"); } /* Prompt */ Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, -1, TERM_SLATE, "Arrow keys allocate points to skills"); Term_putstr(QUESTION_COL, INSTRUCT_ROW + 2, -1, TERM_SLATE, " Enter accept current values"); /* Hack - highlight the key names */ Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, - 1, TERM_L_WHITE, "Arrow keys"); Term_putstr(QUESTION_COL + 5, INSTRUCT_ROW + 2, - 1, TERM_L_WHITE, "Enter"); /* Get key */ hide_cursor = TRUE; ch = inkey(); hide_cursor = FALSE; /* Quit (only if haven't begun game yet) */ if (((ch == 'Q') || (ch == 'q')) && (turn == 0)) quit(NULL); /* Done */ if ((ch == '\r') || (ch == '\n')) { accepted = TRUE; break; } /* Abort */ if (ch == ESCAPE) { p_ptr->new_exp = old_new_exp; for (i=0; i<S_MAX; i++) p_ptr->skill_base[i] = old_base[i]; //p_ptr->csp = old_csp; accepted = FALSE; break; } /* Prev skill */ if (ch == '8') { skill = (skill + S_MAX - 1) % S_MAX; } /* Next skill */ if (ch == '2') { skill = (skill + 1) % S_MAX; } /* Decrease skill */ if ((ch == '4') && (skill_gain[skill] > 0)) { skill_gain[skill]--; } /* Increase stat */ if (ch == '6') { skill_gain[skill]++; } } // reset hack global variable skill_gain_in_progress = FALSE; /* Calculate the bonuses */ p_ptr->update |= (PU_BONUS); /* Update stuff */ update_stuff(); /* Done */ return (accepted); }
/** * Add an item to the players inventory. * * If the new item can combine with an existing item in the inventory, * it will do so, using object_similar() and object_absorb(), else, * the item will be placed into the first available gear array index. * * This function can be used to "over-fill" the player's pack, but only * once, and such an action must trigger the "overflow" code immediately. * Note that when the pack is being "over-filled", the new item must be * placed into the "overflow" slot, and the "overflow" must take place * before the pack is reordered, but (optionally) after the pack is * combined. This may be tricky. See "dungeon.c" for info. * * Note that this code removes any location information from the object once * it is placed into the inventory, but takes no responsibility for removing * the object from any other pile it was in. */ void inven_carry(struct player *p, struct object *obj, bool absorb, bool message) { struct object *gear_obj; char o_name[80]; /* Check for combining, if appropriate */ if (absorb) { for (gear_obj = p->gear; gear_obj; gear_obj = gear_obj->next) { /* Can't stack equipment */ if (object_is_equipped(p->body, gear_obj)) continue; /* Check if the two items can be combined */ if (object_similar(gear_obj, obj, OSTACK_PACK)) { /* Increase the weight */ p->upkeep->total_weight += (obj->number * obj->weight); /* Combine the items, and their known versions */ object_absorb(gear_obj->known, obj->known); obj->known = NULL; object_absorb(gear_obj, obj); /* Describe the combined object */ object_desc(o_name, sizeof(o_name), gear_obj, ODESC_PREFIX | ODESC_FULL); /* Recalculate bonuses */ p->upkeep->update |= (PU_BONUS | PU_INVEN); /* Redraw stuff */ p->upkeep->redraw |= (PR_INVEN); /* Inventory will need updating */ update_stuff(player); /* Optionally, display a message */ if (message) msg("You have %s (%c).", o_name, gear_to_label(gear_obj)); /* Sound for quiver objects */ if (object_is_in_quiver(p, gear_obj)) sound(MSG_QUIVER); /* Success */ return; } } } /* Paranoia */ assert(pack_slots_used(p) <= z_info->pack_size); /* Add to the end of the list */ gear_insert_end(obj); /* Apply an autoinscription */ apply_autoinscription(obj); /* Remove cave object details */ obj->held_m_idx = 0; obj->iy = obj->ix = 0; obj->known->iy = obj->known->ix = 0; /* Update the inventory */ p->upkeep->total_weight += (obj->number * obj->weight); p->upkeep->update |= (PU_BONUS | PU_INVEN); p->upkeep->notice |= (PN_COMBINE); p->upkeep->redraw |= (PR_INVEN); /* Inventory will need updating */ update_stuff(player); /* Hobbits ID mushrooms on pickup, gnomes ID wands and staffs on pickup */ if (!object_flavor_is_aware(obj)) { if (player_has(player, PF_KNOW_MUSHROOM) && tval_is_mushroom(obj)) { object_flavor_aware(obj); msg("Mushrooms for breakfast!"); } else if (player_has(player, PF_KNOW_ZAPPER) && tval_is_zapper(obj)) object_flavor_aware(obj); } /* Optionally, display a message */ if (message) { /* Describe the object */ object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); /* Message */ msg("You have %s (%c).", o_name, gear_to_label(obj)); } /* Sound for quiver objects */ if (object_is_in_quiver(p, obj)) sound(MSG_QUIVER); }
/** * Wield or wear a single item from the pack or floor */ void inven_wield(struct object *obj, int slot) { struct object *wielded, *old = player->body.slots[slot].obj; const char *fmt; char o_name[80]; bool dummy = false; /* Increase equipment counter if empty slot */ if (old == NULL) player->upkeep->equip_cnt++; /* Take a turn */ player->upkeep->energy_use = z_info->move_energy; /* It's either a gear object or a floor object */ if (object_is_carried(player, obj)) { /* Split off a new object if necessary */ if (obj->number > 1) { wielded = gear_object_for_use(obj, 1, false, &dummy); /* The new item needs new gear and known gear entries */ wielded->next = obj->next; obj->next = wielded; wielded->prev = obj; if (wielded->next) (wielded->next)->prev = wielded; wielded->known->next = obj->known->next; obj->known->next = wielded->known; wielded->known->prev = obj->known; if (wielded->known->next) (wielded->known->next)->prev = wielded->known; } else { /* Just use the object directly */ wielded = obj; } } else { /* Get a floor item and carry it */ wielded = floor_object_for_use(obj, 1, false, &dummy); inven_carry(player, wielded, false, false); } /* Wear the new stuff */ player->body.slots[slot].obj = wielded; /* Do any ID-on-wield */ object_learn_on_wield(player, wielded); /* Where is the item now */ if (tval_is_melee_weapon(wielded)) fmt = "You are wielding %s (%c)."; else if (wielded->tval == TV_BOW) fmt = "You are shooting with %s (%c)."; else if (tval_is_light(wielded)) fmt = "Your light source is %s (%c)."; else fmt = "You are wearing %s (%c)."; /* Describe the result */ object_desc(o_name, sizeof(o_name), wielded, ODESC_PREFIX | ODESC_FULL); /* Message */ msgt(MSG_WIELD, fmt, o_name, I2A(slot)); /* Sticky flag geats a special mention */ if (of_has(wielded->flags, OF_STICKY)) { /* Warn the player */ msgt(MSG_CURSED, "Oops! It feels deathly cold!"); } /* See if we have to overflow the pack */ combine_pack(); pack_overflow(old); /* Recalculate bonuses, torch, mana, gear */ player->upkeep->notice |= (PN_IGNORE); player->upkeep->update |= (PU_BONUS | PU_INVEN | PU_UPDATE_VIEW); player->upkeep->redraw |= (PR_INVEN | PR_EQUIP | PR_ARMOR); player->upkeep->redraw |= (PR_STATS | PR_HP | PR_MANA | PR_SPEED); update_stuff(player); /* Disable repeats */ cmd_disable_repeat(); }