X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fxtra2.c;h=77d92ea584bd3d12a4e07ed04ecd019725411a2a;hb=3c26f0ccd00f36abaf409dc18fad7aec0def05bb;hp=b94386edf797bd7747ba127ce3db0f1f3e1b3fea;hpb=c604646ea324593ac15733b70d4c0e4cfc699d38;p=hengband%2Fhengband.git diff --git a/src/xtra2.c b/src/xtra2.c index b94386edf..77d92ea58 100644 --- a/src/xtra2.c +++ b/src/xtra2.c @@ -377,12 +377,59 @@ static bool kind_is_hafted(int k_idx) } +void complete_quest(int quest_num) +{ + quest_type* const q_ptr = &quest[quest_num]; + + switch (q_ptr->type) + { + case QUEST_TYPE_RANDOM: + if (record_rand_quest) do_cmd_write_nikki(NIKKI_RAND_QUEST_C, quest_num, NULL); + break; + default: + if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, quest_num, NULL); + break; + } + + q_ptr->status = QUEST_STATUS_COMPLETED; + q_ptr->complev = (byte)p_ptr->lev; + update_playtime(); + q_ptr->comptime = playtime; + + if (!(q_ptr->flags & QUEST_FLAG_SILENT)) + { + msg_print(_("¥¯¥¨¥¹¥È¤òãÀ®¤·¤¿¡ª", "You just completed your quest!")); + msg_print(NULL); + } +} + +static int count_all_hostile_monsters(void) +{ + int x, y; + int number_mon = 0; + + for (x = 0; x < cur_wid; ++ x) + { + for (y = 0; y < cur_hgt; ++ y) + { + int m_idx = cave[y][x].m_idx; + + if (m_idx > 0 && is_hostile(&m_list[m_idx])) + { + ++ number_mon; + } + } + } + + return number_mon; +} + /* * Check for "Quest" completion when a quest monster is killed or charmed. */ void check_quest_completion(monster_type *m_ptr) { - int i, j, y, x, ny, nx, i2, j2; + int y, x; int quest_num; @@ -397,41 +444,46 @@ void check_quest_completion(monster_type *m_ptr) x = m_ptr->fx; /* Inside a quest */ - quest_num = p_ptr->inside_quest; + quest_num = p_ptr->inside_quest; /* Search for an active quest on this dungeon level */ if (!quest_num) { + int i; + for (i = max_quests - 1; i > 0; i--) { + quest_type* const q_ptr = &quest[i]; + /* Quest is not active */ - if (quest[i].status != QUEST_STATUS_TAKEN) + if (q_ptr->status != QUEST_STATUS_TAKEN) continue; /* Quest is not a dungeon quest */ - if (quest[i].flags & QUEST_FLAG_PRESET) + if (q_ptr->flags & QUEST_FLAG_PRESET) continue; /* Quest is not on this level */ - if ((quest[i].level != dun_level) && - (quest[i].type != QUEST_TYPE_KILL_ANY_LEVEL)) + if ((q_ptr->level != dun_level) && + (q_ptr->type != QUEST_TYPE_KILL_ANY_LEVEL)) continue; /* Not a "kill monster" quest */ - if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) || - (quest[i].type == QUEST_TYPE_FIND_EXIT)) + if ((q_ptr->type == QUEST_TYPE_FIND_ARTIFACT) || + (q_ptr->type == QUEST_TYPE_FIND_EXIT)) continue; /* Interesting quest */ - if ((quest[i].type == QUEST_TYPE_KILL_NUMBER) || - (quest[i].type == QUEST_TYPE_KILL_ALL)) + if ((q_ptr->type == QUEST_TYPE_KILL_NUMBER) || + (q_ptr->type == QUEST_TYPE_TOWER) || + (q_ptr->type == QUEST_TYPE_KILL_ALL)) break; /* Interesting quest */ - if (((quest[i].type == QUEST_TYPE_KILL_LEVEL) || - (quest[i].type == QUEST_TYPE_KILL_ANY_LEVEL) || - (quest[i].type == QUEST_TYPE_RANDOM)) && - (quest[i].r_idx == m_ptr->r_idx)) + if (((q_ptr->type == QUEST_TYPE_KILL_LEVEL) || + (q_ptr->type == QUEST_TYPE_KILL_ANY_LEVEL) || + (q_ptr->type == QUEST_TYPE_RANDOM)) && + (q_ptr->r_idx == m_ptr->r_idx)) break; } @@ -442,68 +494,35 @@ void check_quest_completion(monster_type *m_ptr) if (quest_num && (quest[quest_num].status == QUEST_STATUS_TAKEN)) { /* Current quest */ - i = quest_num; + quest_type* const q_ptr = &quest[quest_num]; - switch (quest[i].type) + switch (q_ptr->type) { case QUEST_TYPE_KILL_NUMBER: { - quest[i].cur_num++; + q_ptr->cur_num++; - if (quest[i].cur_num >= quest[i].num_mon) + if (q_ptr->cur_num >= q_ptr->num_mon) { - if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, i, NULL); - /* completed quest */ - quest[i].status = QUEST_STATUS_COMPLETED; - quest[i].complev = (byte)p_ptr->lev; + complete_quest(quest_num); - if (!(quest[i].flags & QUEST_FLAG_SILENT)) - { -#ifdef JP -msg_print("¥¯¥¨¥¹¥È¤òãÀ®¤·¤¿¡ª"); -#else - msg_print("You just completed your quest!"); -#endif - - msg_print(NULL); - } - - quest[i].cur_num = 0; + q_ptr->cur_num = 0; } break; } case QUEST_TYPE_KILL_ALL: { - int number_mon = 0; - if (!is_hostile(m_ptr)) break; - /* Count all hostile monsters */ - for (i2 = 0; i2 < cur_wid; ++i2) - for (j2 = 0; j2 < cur_hgt; j2++) - if (cave[j2][i2].m_idx > 0) - if (is_hostile(&m_list[cave[j2][i2].m_idx])) - number_mon++; - - if ((number_mon - 1) == 0) + if (count_all_hostile_monsters() == 1) { - if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, i, NULL); - /* completed */ - if (quest[i].flags & QUEST_FLAG_SILENT) + if (q_ptr->flags & QUEST_FLAG_SILENT) { - quest[i].status = QUEST_STATUS_FINISHED; + q_ptr->status = QUEST_STATUS_FINISHED; } else { - quest[i].status = QUEST_STATUS_COMPLETED; - quest[i].complev = (byte)p_ptr->lev; -#ifdef JP -msg_print("¥¯¥¨¥¹¥È¤òãÀ®¤·¤¿¡ª"); -#else - msg_print("You just completed your quest!"); -#endif - - msg_print(NULL); + complete_quest(quest_num); } } break; @@ -512,70 +531,60 @@ msg_print(" case QUEST_TYPE_RANDOM: { /* Only count valid monsters */ - if (quest[i].r_idx != m_ptr->r_idx) + if (q_ptr->r_idx != m_ptr->r_idx) break; - quest[i].cur_num++; + q_ptr->cur_num++; - if (quest[i].cur_num >= quest[i].max_num) + if (q_ptr->cur_num >= q_ptr->max_num) { - if (record_fix_quest && (quest[i].type == QUEST_TYPE_KILL_LEVEL)) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, i, NULL); - if (record_rand_quest && (quest[i].type == QUEST_TYPE_RANDOM)) do_cmd_write_nikki(NIKKI_RAND_QUEST_C, i, NULL); - /* completed quest */ - quest[i].status = QUEST_STATUS_COMPLETED; - quest[i].complev = (byte)p_ptr->lev; - if (!(quest[i].flags & QUEST_FLAG_PRESET)) + complete_quest(quest_num); + + if (!(q_ptr->flags & QUEST_FLAG_PRESET)) { create_stairs = TRUE; p_ptr->inside_quest = 0; } - if (!(quest[i].flags & QUEST_FLAG_SILENT)) - { -#ifdef JP -msg_print("¥¯¥¨¥¹¥È¤òãÀ®¤·¤¿¡ª"); -#else - msg_print("You just completed your quest!"); -#endif - - msg_print(NULL); - } - /* Finish the two main quests without rewarding */ - if ((i == QUEST_OBERON) || (i == QUEST_SERPENT)) + if ((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT)) { - quest[i].status = QUEST_STATUS_FINISHED; + q_ptr->status = QUEST_STATUS_FINISHED; } - if (quest[i].type == QUEST_TYPE_RANDOM) + if (q_ptr->type == QUEST_TYPE_RANDOM) { reward = TRUE; - quest[i].status = QUEST_STATUS_FINISHED; + q_ptr->status = QUEST_STATUS_FINISHED; } } break; } case QUEST_TYPE_KILL_ANY_LEVEL: { - quest[i].cur_num++; - if (quest[i].cur_num >= quest[i].max_num) + q_ptr->cur_num++; + if (q_ptr->cur_num >= q_ptr->max_num) { - if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, i, NULL); - /* completed quest */ - quest[i].status = QUEST_STATUS_COMPLETED; - quest[i].complev = (byte)p_ptr->lev; + complete_quest(quest_num); + q_ptr->cur_num = 0; + } + break; + } + case QUEST_TYPE_TOWER: + { + if (!is_hostile(m_ptr)) break; - if (!(quest[i].flags & QUEST_FLAG_SILENT)) + if (count_all_hostile_monsters() == 1) + { + q_ptr->status = QUEST_STATUS_STAGE_COMPLETED; + + if((quest[QUEST_TOWER1].status == QUEST_STATUS_STAGE_COMPLETED) && + (quest[QUEST_TOWER2].status == QUEST_STATUS_STAGE_COMPLETED) && + (quest[QUEST_TOWER3].status == QUEST_STATUS_STAGE_COMPLETED)) { -#ifdef JP -msg_print("¥¯¥¨¥¹¥È¤òãÀ®¤·¤¿¡ª"); -#else - msg_print("You just completed your quest!"); -#endif - msg_print(NULL); + complete_quest(QUEST_TOWER1); } - quest[i].cur_num = 0; } break; } @@ -585,6 +594,8 @@ msg_print(" /* Create a magical staircase */ if (create_stairs) { + int ny, nx; + /* Stagger around */ while (cave_perma_bold(y, x) || cave[y][x].o_idx || (cave[y][x].info & CAVE_OBJECT) ) { @@ -615,7 +626,9 @@ msg_print(" */ if (reward) { - for (j = 0; j < (dun_level / 15)+1; j++) + int i; + + for (i = 0; i < (dun_level / 15)+1; i++) { /* Get local object */ q_ptr = &forge; @@ -633,6 +646,21 @@ msg_print(" } +void check_find_art_quest_completion(object_type *o_ptr) +{ + int i; + /* Check if completed a quest */ + for (i = 0; i < max_quests; i++) + { + if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) && + (quest[i].status == QUEST_STATUS_TAKEN) && + (quest[i].k_idx == o_ptr->name1)) + { + complete_quest(i); + } + } +} + /* * Return monster death string */ @@ -698,7 +726,7 @@ void monster_death(int m_idx, bool drop_item) monster_race *r_ptr = &r_info[m_ptr->r_idx]; - bool visible = (m_ptr->ml || (r_ptr->flags1 & RF1_UNIQUE)); + bool visible = ((m_ptr->ml && !p_ptr->image) || (r_ptr->flags1 & RF1_UNIQUE)); u32b mo_mode = 0L; @@ -1305,8 +1333,16 @@ msg_print(" break; case MON_SURTUR: - a_idx = ART_TWILIGHT; - chance = 66; + if (!one_in_(3)) + { + a_idx = ART_TWILIGHT; + chance = 100; + } + else + { + a_idx = ART_ORB_OF_FATE; + chance = 100; + } break; case MON_SARUMAN: @@ -1388,6 +1424,17 @@ msg_print(" a_idx = ART_FUNDIN; chance = 5; break; + + case MON_ROBIN_HOOD: + a_idx = ART_ROBIN_HOOD; + chance = 5; + break; + + case MON_KOGAN: + a_idx = ART_NANACHO; + chance = 80; + break; + } if ((a_idx > 0) && ((randint0(100) < chance) || p_ptr->wizard)) @@ -1470,6 +1517,9 @@ msg_print(" if (is_pet(m_ptr) || p_ptr->inside_battle || p_ptr->inside_arena) number = 0; /* Pets drop no stuff */ if (!drop_item && (r_ptr->d_char != '$')) number = 0; + + if((r_ptr->flags2 & (RF2_MULTIPLY)) && (r_ptr->r_akills > 1024)) + number = 0; /* Limit of Multiply monster drop */ /* Hack -- handle creeping coins */ coin_type = force_coin; @@ -1672,6 +1722,20 @@ static void get_exp_from_mon(int dam, monster_type *m_ptr) s64b_RSHIFT(new_exp, new_exp_frac, 2); } } + + /* Special penalty for rest_and_shoot exp scum */ + if ((m_ptr->dealt_damage > m_ptr->max_maxhp) && (m_ptr->hp >= 0)) + { + int over_damage = m_ptr->dealt_damage / m_ptr->max_maxhp; + if (over_damage > 32) over_damage = 32; + + while (over_damage--) + { + /* 9/10 for once */ + s64b_mul(&new_exp, &new_exp_frac, 0, 9); + s64b_div(&new_exp, &new_exp_frac, 0, 10); + } + } /* Finally multiply base experience point of the monster */ s64b_mul(&new_exp, &new_exp_frac, 0, r_ptr->mexp); @@ -1721,16 +1785,17 @@ bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note) bool innocent = TRUE, thief = FALSE; int i; int expdam; + int dealt_damage; - COPY(&exp_mon, m_ptr, monster_type); - if (!(r_ptr->flags7 & RF7_KILL_EXP)) - { - expdam = (m_ptr->hp > dam) ? dam : m_ptr->hp; - if (r_ptr->flags6 & RF6_HEAL) expdam = (expdam+1) * 2 / 3; + (void)COPY(&exp_mon, m_ptr, monster_type); + + expdam = (m_ptr->hp > dam) ? dam : m_ptr->hp; - get_exp_from_mon(expdam, &exp_mon); - } + get_exp_from_mon(expdam, &exp_mon); + /* Genocided by chaos patron */ + if (!m_ptr->r_idx) m_idx = 0; + /* Redraw (later) if needed */ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH); @@ -1744,8 +1809,22 @@ bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note) set_superstealth(FALSE); } + /* Genocided by chaos patron */ + if (!m_idx) return TRUE; + + /* Remember dealt_damage before this attack*/ + dealt_damage = m_ptr->dealt_damage; + /* Hurt it */ m_ptr->hp -= dam; + + m_ptr->dealt_damage += dam; + if(m_ptr->dealt_damage > m_ptr->max_maxhp * 100) m_ptr->dealt_damage = m_ptr->max_maxhp * 100; + if (p_ptr->wizard) + { + msg_format( _("¹ç·×%d/%d¤Î¥À¥á¡¼¥¸¤òÍ¿¤¨¤¿¡£","You do %d (out of %d) damage."), + m_ptr->dealt_damage, m_ptr->maxhp); + } /* It is dead now */ if (m_ptr->hp < 0) @@ -1803,7 +1882,7 @@ bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note) if (r_ptr->r_akills < MAX_SHORT) r_ptr->r_akills++; /* Recall even invisible uniques or winners */ - if (m_ptr->ml || (r_ptr->flags1 & RF1_UNIQUE)) + if ((m_ptr->ml && !p_ptr->image) || (r_ptr->flags1 & RF1_UNIQUE)) { /* Count kills this life */ if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_pkills < MAX_SHORT)) r_info[MON_KAGE].r_pkills++; @@ -2098,11 +2177,7 @@ msg_format("%s delete_monster_idx(m_idx); } - /* Prevent bug of chaos patron's reward */ - if (r_ptr->flags7 & RF7_KILL_EXP) - get_exp_from_mon((long)exp_mon.max_maxhp*2, &exp_mon); - else - get_exp_from_mon(((long)exp_mon.max_maxhp+1L) * 9L / 10L, &exp_mon); + get_exp_from_mon((long)exp_mon.max_maxhp*2, &exp_mon); /* Not afraid */ (*fear) = FALSE; @@ -2330,6 +2405,24 @@ bool change_panel(int dy, int dx) return (FALSE); } +bool change_panel_xy(int y, int x) +{ + int dy = 0, dx = 0; + int wid, hgt; + + /* Get size */ + get_screen_size(&wid, &hgt); + + if (y < panel_row_min) dy = -1; + if (y > panel_row_max) dy = 1; + if (x < panel_col_min) dx = -1; + if (x > panel_col_max) dx = 1; + + if (!dy && !dx) return (FALSE); + + return change_panel(dy, dx); +} + /* * Given an row (y) and col (x), this routine detects when a move @@ -2967,14 +3060,32 @@ static bool target_set_accept(int y, int x) static void target_set_prepare(int mode) { int y, x; + int min_hgt, max_hgt, min_wid, max_wid; + + if (mode & TARGET_KILL) + { + /* Inner range */ + min_hgt = MAX((py - MAX_RANGE), 0); + max_hgt = MIN((py + MAX_RANGE), cur_hgt - 1); + min_wid = MAX((px - MAX_RANGE), 0); + max_wid = MIN((px + MAX_RANGE), cur_wid - 1); + } + else /* not targetting */ + { + /* Inner panel */ + min_hgt = panel_row_min; + max_hgt = panel_row_max; + min_wid = panel_col_min; + max_wid = panel_col_max; + } /* Reset "temp" array */ temp_n = 0; /* Scan the current panel */ - for (y = panel_row_min; y <= panel_row_max; y++) + for (y = min_hgt; y <= max_hgt; y++) { - for (x = panel_col_min; x <= panel_col_max; x++) + for (x = min_wid; x <= max_wid; x++) { cave_type *c_ptr; @@ -3024,6 +3135,9 @@ static void target_set_prepare(int mode) temp_x[1] = tmp; } } +void target_set_prepare_look(){ + target_set_prepare(TARGET_LOOK); +} /* @@ -3077,10 +3191,12 @@ static void evaluate_monster_exp(char *buf, monster_type *m_ptr) num = MIN(999, exp_adv_frac); /* Display the number */ - sprintf(buf,"%03ld", num); + sprintf(buf,"%03ld", (long int)num); } +bool show_gold_on_floor = FALSE; + /* * Examine a grid, return a keypress. * @@ -3432,7 +3548,9 @@ static int target_set_aux(int y, int x, int mode, cptr info) screen_save(); /* Display */ + show_gold_on_floor = TRUE; (void)show_floor(0, y, x, &min_width); + show_gold_on_floor = FALSE; /* Prompt */ #ifdef JP @@ -3567,8 +3685,36 @@ static int target_set_aux(int y, int x, int mode, cptr info) { cptr name; + /* Hack -- special handling for quest entrances */ + if (have_flag(f_ptr->flags, FF_QUEST_ENTER)) + { + /* Set the quest number temporary */ + int old_quest = p_ptr->inside_quest; + int j; + + /* Clear the text */ + for (j = 0; j < 10; j++) quest_text[j][0] = '\0'; + quest_text_line = 0; + + p_ptr->inside_quest = c_ptr->special; + + /* Get the quest text */ + init_flags = INIT_NAME_ONLY; + + process_dungeon_file("q_info.txt", 0, 0, 0, 0); + +#ifdef JP + name = format("¥¯¥¨¥¹¥È¡Ö%s¡×(%d³¬ÁêÅö)", quest[c_ptr->special].name, quest[c_ptr->special].level); +#else + name = format("the entrance to the quest '%s'(level %d)", quest[c_ptr->special].name, quest[c_ptr->special].level); +#endif + + /* Reset the old quest number */ + p_ptr->inside_quest = old_quest; + } + /* Hack -- special handling for building doors */ - if (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena) + else if (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena) { name = building[f_ptr->subtype].name; } @@ -3613,6 +3759,7 @@ static int target_set_aux(int y, int x, int mode, cptr info) /* Hack -- special introduction for store & building doors -KMW- */ if (have_flag(f_ptr->flags, FF_STORE) || + have_flag(f_ptr->flags, FF_QUEST_ENTER) || (have_flag(f_ptr->flags, FF_BLDG) && !p_ptr->inside_arena) || have_flag(f_ptr->flags, FF_ENTRANCE)) { @@ -3644,7 +3791,7 @@ static int target_set_aux(int y, int x, int mode, cptr info) if (c_ptr->mimic) sprintf(f_idx_str, "%d/%d", c_ptr->feat, c_ptr->mimic); else sprintf(f_idx_str, "%d", c_ptr->feat); #ifdef JP - sprintf(out_val, "%s%s%s%s[%s] %x %s %d %d %d (%d,%d)", s1, name, s2, s3, info, c_ptr->info, f_idx_str, c_ptr->dist, c_ptr->cost, c_ptr->when, y, x); + sprintf(out_val, "%s%s%s%s[%s] %x %s %d %d %d (%d,%d) %d", s1, name, s2, s3, info, c_ptr->info, f_idx_str, c_ptr->dist, c_ptr->cost, c_ptr->when, y, x, travel.cost[y][x]); #else sprintf(out_val, "%s%s%s%s [%s] %x %s %d %d %d (%d,%d)", s1, s2, s3, name, info, c_ptr->info, f_idx_str, c_ptr->dist, c_ptr->cost, c_ptr->when, y, x); #endif @@ -3730,8 +3877,7 @@ bool target_set(int mode) cave_type *c_ptr; int wid, hgt; - - + /* Get size */ get_screen_size(&wid, &hgt); @@ -3758,6 +3904,9 @@ bool target_set(int mode) y = temp_y[m]; x = temp_x[m]; + /* Set forcus */ + change_panel_xy(y, x); + if (!(mode & TARGET_LOOK)) prt_path(y, x); /* Access */ @@ -3784,9 +3933,12 @@ strcpy(info, "q #endif } - + /* Describe and Prompt */ - while (!(query = target_set_aux(y, x, mode, info))); + while (TRUE){ + query = target_set_aux(y, x, mode, info); + if(query)break; + } /* Cancel tracking */ /* health_track(0); */ @@ -4382,6 +4534,7 @@ msg_print(" bool get_rep_dir(int *dp, bool under) { int dir; + cptr prompt; /* Initialize */ (*dp) = 0; @@ -4399,24 +4552,36 @@ bool get_rep_dir(int *dp, bool under) #endif /* ALLOW_REPEAT -- TNB */ + if (under) + { + prompt = _("Êý¸þ ('.'­¸µ, ESC¤ÇÃæÃÇ)? ", "Direction ('.' at feet, Escape to cancel)? "); + } + else + { + prompt = _("Êý¸þ (ESC¤ÇÃæÃÇ)? ", "Direction (Escape to cancel)? "); + } + /* Get a direction */ while (!dir) { char ch; /* Get a command (or Cancel) */ -#ifdef JP -if (!get_com("Êý¸þ (ESC¤ÇÃæÃÇ)? ", &ch, TRUE)) break; -#else - if (!get_com("Direction (Escape to cancel)? ", &ch, TRUE)) break; -#endif + if (!get_com(prompt, &ch, TRUE)) break; + /* Look down */ + if ((under) && ((ch == '5') || (ch == '-') || (ch == '.'))) + { + dir = 5; + } + else + { + /* Look up the direction */ + dir = get_keymap_dir(ch); - /* Look up the direction */ - dir = get_keymap_dir(ch); - - /* Oops */ - if (!dir) bell(); + /* Oops */ + if (!dir) bell(); + } } /* Prevent weirdness */ @@ -4603,7 +4768,6 @@ msg_print(" return (TRUE); } - void gain_level_reward(int chosen_reward) { object_type *q_ptr; @@ -5581,12 +5745,85 @@ msg_format(" /* + * XAngband: determine if a given location is "interesting" + * based on target_set_accept function. + */ +static bool tgt_pt_accept(int y, int x) +{ + cave_type *c_ptr; + + /* Bounds */ + if (!(in_bounds(y, x))) return (FALSE); + + /* Player grid is always interesting */ + if ((y == py) && (x == px)) return (TRUE); + + /* Handle hallucination */ + if (p_ptr->image) return (FALSE); + + /* Examine the grid */ + c_ptr = &cave[y][x]; + + /* Interesting memorized features */ + if (c_ptr->info & (CAVE_MARK)) + { + /* Notice stairs */ + if (cave_have_flag_grid(c_ptr, FF_LESS)) return (TRUE); + if (cave_have_flag_grid(c_ptr, FF_MORE)) return (TRUE); + + /* Notice quest features */ + if (cave_have_flag_grid(c_ptr, FF_QUEST_ENTER)) return (TRUE); + if (cave_have_flag_grid(c_ptr, FF_QUEST_EXIT)) return (TRUE); + } + + /* Nope */ + return (FALSE); +} + + +/* + * XAngband: Prepare the "temp" array for "tget_pt" + * based on target_set_prepare funciton. + */ +static void tgt_pt_prepare(void) +{ + int y, x; + + /* Reset "temp" array */ + temp_n = 0; + + if (!expand_list) return; + + /* Scan the current panel */ + for (y = 1; y < cur_hgt; y++) + { + for (x = 1; x < cur_wid; x++) + { + /* Require "interesting" contents */ + if (!tgt_pt_accept(y, x)) continue; + + /* Save the location */ + temp_x[temp_n] = x; + temp_y[temp_n] = y; + temp_n++; + } + } + + /* Target the nearest monster for shooting */ + ang_sort_comp = ang_sort_comp_distance; + ang_sort_swap = ang_sort_swap_distance; + + /* Sort the positions */ + ang_sort(temp_x, temp_y, temp_n); +} + +/* * old -- from PsiAngband. */ bool tgt_pt(int *x_ptr, int *y_ptr) { char ch = 0; - int d, x, y; + int d, x, y, n; bool success = FALSE; int wid, hgt; @@ -5597,8 +5834,14 @@ bool tgt_pt(int *x_ptr, int *y_ptr) x = px; y = py; + if (expand_list) + { + tgt_pt_prepare(); + n = 0; + } + #ifdef JP -msg_print("¾ì½ê¤òÁª¤ó¤Ç¥¹¥Ú¡¼¥¹¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£"); + msg_print("¾ì½ê¤òÁª¤ó¤Ç¥¹¥Ú¡¼¥¹¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£"); #else msg_print("Select a point and press space."); #endif @@ -5626,6 +5869,62 @@ msg_print(" else success = TRUE; break; + + /* XAngband: Move cursor to stairs */ + case '>': + case '<': + if (expand_list && temp_n) + { + int dx, dy; + int cx = (panel_col_min + panel_col_max) / 2; + int cy = (panel_row_min + panel_row_max) / 2; + + n++; + + /* Skip stairs which have defferent distance */ + for (; n < temp_n; ++ n) + { + cave_type *c_ptr = &cave[temp_y[n]][temp_x[n]]; + + if (cave_have_flag_grid(c_ptr, FF_STAIRS) && + cave_have_flag_grid(c_ptr, ch == '>' ? FF_MORE : FF_LESS)) + { + /* Found */ + break; + } + } + + if (n == temp_n) /* Loop out taget list */ + { + n = 0; + y = py; + x = px; + verify_panel(); /* Move cursor to player */ + + /* Update stuff */ + p_ptr->update |= (PU_MONSTERS); + + /* Redraw map */ + p_ptr->redraw |= (PR_MAP); + + /* Window stuff */ + p_ptr->window |= (PW_OVERHEAD); + + /* Handle stuff */ + handle_stuff(); + } + else /* move cursor to next stair and change panel */ + { + y = temp_y[n]; + x = temp_x[n]; + + dy = 2 * (y - cy) / hgt; + dx = 2 * (x - cx) / wid; + if (dy || dx) change_panel(dy, dx); + } + } + break; + default: /* Look up the direction */ d = get_keymap_dir(ch); @@ -6028,3 +6327,166 @@ int spell_exp_level(int spell_exp) else if (spell_exp < SPELL_EXP_MASTER) return EXP_LEVEL_EXPERT; else return EXP_LEVEL_MASTER; } + + +/* + * Display a rumor and apply its effects + */ + +int rumor_num(char *zz, int max_idx) +{ + if (strcmp(zz, "*") == 0) return randint1(max_idx - 1); + return atoi(zz); +} + +cptr rumor_bind_name(char *base, cptr fullname) +{ + char *s, *v; + + s = strstr(base, "{Name}"); + if (s) + { + s[0] = '\0'; + v = format("%s%s%s", base, fullname, (s + 6)); + } + else + { + v = base; + } + + return v; +} + +void display_rumor(bool ex) +{ + bool err; + int section = 0; + char Rumor[1024]; + + if (ex) + { + if (randint0(3) == 0) section = 1; + } + +#ifdef JP + err = get_rnd_line_jonly("rumors_j.txt", section, Rumor, 10); + if (err) strcpy(Rumor, "±³¤Î±½¤â¤¢¤ë¡£"); +#else + err = get_rnd_line("rumors.txt", section, Rumor); + if (err) strcpy(Rumor, "Some rumors are wrong."); +#endif + + err = TRUE; + + if (strncmp(Rumor, "R:", 2) == 0) + { + char *zz[4]; + cptr rumor_msg = NULL; + cptr rumor_eff_format = NULL; + char fullname[1024] = ""; + + if (tokenize(Rumor + 2, 3, zz, TOKENIZE_CHECKQUOTE) == 3) + { + if (strcmp(zz[0], "ARTIFACT") == 0) + { + int a_idx, k_idx; + object_type forge; + object_type *q_ptr = &forge; + artifact_type *a_ptr; + + while (1) + { + a_idx = rumor_num(zz[1], max_a_idx); + + a_ptr = &a_info[a_idx]; + if (a_ptr->name) break; + } + + k_idx = lookup_kind(a_ptr->tval, a_ptr->sval); + object_prep(q_ptr, k_idx); + q_ptr->name1 = a_idx; + q_ptr->ident = IDENT_STORE; + object_desc(fullname, q_ptr, OD_NAME_ONLY); + } + else if (strcmp(zz[0], "MONSTER") == 0) + { + int r_idx; + monster_race *r_ptr; + + while(1) + { + r_idx = rumor_num(zz[1], max_r_idx); + r_ptr = &r_info[r_idx]; + if (r_ptr->name) break; + } + + strcpy(fullname, r_name + r_ptr->name); + + /* Remember this monster */ + if (!r_ptr->r_sights) + { + r_ptr->r_sights++; + } + } + else if (strcmp(zz[0], "DUNGEON") == 0) + { + int d_idx; + dungeon_info_type *d_ptr; + + while (1) + { + d_idx = rumor_num(zz[1], max_d_idx); + d_ptr = &d_info[d_idx]; + if (d_ptr->name) break; + } + + strcpy(fullname, d_name + d_ptr->name); + + if (!max_dlv[d_idx]) + { + max_dlv[d_idx] = d_ptr->mindepth; + rumor_eff_format = _("%s¤Ëµ¢´Ô¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡£", "You can recall to %s."); + } + } + else if (strcmp(zz[0], "TOWN") == 0) + { + int t_idx; + s32b visit; + + while(1) + { + t_idx = rumor_num(zz[1], NO_TOWN); + if (town[t_idx].name) break; + } + + strcpy(fullname, town[t_idx].name); + + visit = (1L << (t_idx - 1)); + if ((t_idx != SECRET_TOWN) && !(p_ptr->visit & visit)) + { + p_ptr->visit |= visit; + rumor_eff_format = _("%s¤Ë¹Ô¤Ã¤¿¤³¤È¤¬¤¢¤ëµ¤¤¬¤¹¤ë¡£", "You feel you have been to %s."); + } + } + + rumor_msg = rumor_bind_name(zz[2], fullname); + msg_print(rumor_msg); + if (rumor_eff_format) + { + msg_print(NULL); + msg_format(rumor_eff_format, fullname); + } + err = FALSE; + } + /* error */ +#ifdef JP + if (err) msg_print("¤³¤Î¾ðÊó¤Ï´Ö°ã¤Ã¤Æ¤¤¤ë¡£"); +#else + if (err) msg_print("This information is wrong."); +#endif + } + else + { + msg_format("%s", Rumor); + } +}