にまとめて整理. この過程で以下の変更と修正を含む.
* 0.0.3のセーブファイルから変換する際に, 日替わり賞金首のレベルの下限
がMAX(鉄獄の到達階, 40)になっていたのでMAX(鉄獄の到達階/2, 40)とな
るように修正.
* SPECIAL持ちというだけでは賞金首/クエスターから外されないようにした.
『バーノール=ルパート』などに関しては, クエスターにも賞金首にもなっ
てはならないモンスターIDをまとめた関数を作って判定することとした.
これで, SPECIAL技を持つユニークを賞金首/クエスターにできる.
* セーブデータロード時のランダムクエスター決定でのモンスターテーブル
作成に通常時同様monster_quest()が使われるように修正.
}
}
+
+/*
+ * Determine the random quest uniques
+ */
+void determine_random_questor(quest_type *q_ptr)
+{
+ int r_idx;
+ monster_race *r_ptr;
+
+ /* Prepare allocation table */
+ get_mon_num_prep(monster_quest, NULL);
+
+ while (1)
+ {
+ /*
+ * Random monster 5 - 10 levels out of depth
+ * (depending on level)
+ */
+ r_idx = get_mon_num(q_ptr->level + 5 + randint1(q_ptr->level / 10));
+ r_ptr = &r_info[r_idx];
+
+ if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
+
+ if (r_ptr->flags1 & RF1_QUESTOR) continue;
+
+ if (r_ptr->rarity > 100) continue;
+
+ if (r_ptr->flags7 & RF7_FRIENDLY) continue;
+
+ if (r_ptr->flags7 & RF7_AQUATIC) continue;
+
+ if (r_ptr->flags8 & RF8_WILD_ONLY) continue;
+
+ if (no_questor_or_bounty_uniques(r_idx)) continue;
+
+ /*
+ * Accept monsters that are 2 - 6 levels
+ * out of depth depending on the quest level
+ */
+ if (r_ptr->level > (q_ptr->level + (q_ptr->level / 20))) break;
+ }
+
+ q_ptr->r_idx = r_idx;
+}
+
+
/*
* Initialize random quests and final quests
*/
p_ptr->inside_quest = 0;
- /* Prepare allocation table */
- get_mon_num_prep(monster_quest, NULL);
-
/* Remove QUESTOR flag */
for (i = 1; i < max_r_idx; i++)
{
{
quest_type *q_ptr = &quest[i];
monster_race *quest_r_ptr;
- int r_idx;
q_ptr->status = QUEST_STATUS_TAKEN;
-
- while (1)
- {
- /*
- * Random monster 5 - 10 levels out of depth
- * (depending on level)
- */
- r_idx = get_mon_num(q_ptr->level + 5 + randint1(q_ptr->level / 10));
- r_ptr = &r_info[r_idx];
-
- if(!(r_ptr->flags1 & RF1_UNIQUE)) continue;
-
- if(r_ptr->flags1 & RF1_QUESTOR) continue;
-
- if(r_ptr->flags6 & RF6_SPECIAL) continue;
-
- if(r_ptr->flags7 & RF7_FRIENDLY) continue;
-
- if(r_ptr->flags7 & RF7_AQUATIC) continue;
-
- if(r_ptr->flags8 & RF8_WILD_ONLY) continue;
-
- /*
- * Accept monsters that are 2 - 6 levels
- * out of depth depending on the quest level
- */
- if (r_ptr->level > (q_ptr->level + (q_ptr->level / 20))) break;
- }
-
- q_ptr->r_idx = r_idx;
- quest_r_ptr = &r_info[q_ptr->r_idx];
+ determine_random_questor(q_ptr);
/* Mark uniques */
+ quest_r_ptr = &r_info[q_ptr->r_idx];
quest_r_ptr->flags1 |= RF1_QUESTOR;
q_ptr->max_num = 1;
if (!hour && !min)
{
- monster_race *r_ptr;
-
if (min != prev_min)
{
- int max_dl = 3;
- bool old_inside_battle = p_ptr->inside_battle;
-
do_cmd_write_nikki(NIKKI_HIGAWARI, 0, NULL);
-
- p_ptr->inside_battle = TRUE;
- get_mon_num_prep(NULL,NULL);
-
- for (i = 0; i < max_d_idx; i++)
- {
- if (max_dlv[i] < d_info[i].mindepth) continue;
- if (max_dl < max_dlv[i]) max_dl = max_dlv[i];
- }
- while (1)
- {
- today_mon = get_mon_num(max_dl);
- r_ptr = &r_info[today_mon];
-
- if (r_ptr->flags1 & RF1_UNIQUE) continue;
- if (r_ptr->flags7 & (RF7_UNIQUE_7 | RF7_UNIQUE2)) continue;
- if (r_ptr->flags2 & (RF2_MULTIPLY)) continue;
- if (!(r_ptr->flags9 & RF9_DROP_CORPSE) || !(r_ptr->flags9 & RF9_DROP_SKELETON)) continue;
- if (r_ptr->level < MIN(max_dl/2, 40)) continue;
- if (r_ptr->rarity > 10) continue;
- if (r_ptr->level == 0) continue;
- break;
- }
- p_ptr->today_mon = 0;
- p_ptr->inside_battle = old_inside_battle;
+ determine_today_mon(FALSE);
}
}
/*
+ * Determine bounty uniques
+ */
+void determine_bounty_uniques(void)
+{
+ int i, j, tmp;
+ monster_race *r_ptr;
+
+ get_mon_num_prep(NULL, NULL);
+ for (i = 0; i < MAX_KUBI; i++)
+ {
+ while (1)
+ {
+ kubi_r_idx[i] = get_mon_num(MAX_DEPTH - 1);
+ r_ptr = &r_info[kubi_r_idx[i]];
+
+ if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
+
+ if (!(r_ptr->flags9 & RF9_DROP_CORPSE)) continue;
+
+ if (r_ptr->rarity > 100) continue;
+
+ if (no_questor_or_bounty_uniques(kubi_r_idx[i])) continue;
+
+ for (j = 0; j < i; j++)
+ if (kubi_r_idx[i] == kubi_r_idx[j]) break;
+
+ if (j == i) break;
+ }
+ }
+
+ /* Sort them */
+ for (i = 0; i < MAX_KUBI - 1; i++)
+ {
+ for (j = i; j < MAX_KUBI; j++)
+ {
+ if (r_info[kubi_r_idx[i]].level > r_info[kubi_r_idx[j]].level)
+ {
+ tmp = kubi_r_idx[i];
+ kubi_r_idx[i] = kubi_r_idx[j];
+ kubi_r_idx[j] = tmp;
+ }
+ }
+ }
+}
+
+
+/*
+ * Determine today's bounty monster
+ * Note: conv_old is used if loaded 0.0.3 or older save file
+ */
+void determine_today_mon(bool conv_old)
+{
+ int max_dl = 3, i;
+ bool old_inside_battle = p_ptr->inside_battle;
+ monster_race *r_ptr;
+
+ if (!conv_old)
+ {
+ for (i = 0; i < max_d_idx; i++)
+ {
+ if (max_dlv[i] < d_info[i].mindepth) continue;
+ if (max_dl < max_dlv[i]) max_dl = max_dlv[i];
+ }
+ }
+ else max_dl = MAX(max_dlv[DUNGEON_ANGBAND], 3);
+
+ p_ptr->inside_battle = TRUE;
+ get_mon_num_prep(NULL, NULL);
+
+ while (1)
+ {
+ today_mon = get_mon_num(max_dl);
+ r_ptr = &r_info[today_mon];
+
+ if (r_ptr->flags1 & RF1_UNIQUE) continue;
+ if (r_ptr->flags7 & (RF7_UNIQUE_7 | RF7_UNIQUE2)) continue;
+ if (r_ptr->flags2 & RF2_MULTIPLY) continue;
+ if ((r_ptr->flags9 & (RF9_DROP_CORPSE | RF9_DROP_SKELETON)) != (RF9_DROP_CORPSE | RF9_DROP_SKELETON)) continue;
+ if (r_ptr->level < MIN(max_dl / 2, 40)) continue;
+ if (r_ptr->rarity > 10) continue;
+ break;
+ }
+
+ p_ptr->today_mon = 0;
+ p_ptr->inside_battle = old_inside_battle;
+}
+
+
+/*
* Actually play a game
*
* If the "new_game" parameter is true, then, after loading the
/* Roll new character */
if (new_game)
{
- monster_race *r_ptr;
-
/* The dungeon is not ready */
character_dungeon = FALSE;
#endif
load = FALSE;
- get_mon_num_prep(NULL, NULL);
- for (i = 0; i < MAX_KUBI; i++)
- {
- while (1)
- {
- int j;
-
- kubi_r_idx[i] = get_mon_num(MAX_DEPTH - 1);
- r_ptr = &r_info[kubi_r_idx[i]];
- if(!(r_ptr->flags1 & RF1_UNIQUE)) continue;
-
- if(!(r_ptr->flags9 & RF9_DROP_CORPSE)) continue;
- if (r_ptr->rarity > 100) continue;
-
- if(r_ptr->flags6 & RF6_SPECIAL) continue;
-
- for (j = 0; j < i; j++)
- if (kubi_r_idx[i] == kubi_r_idx[j])break;
-
- if (j == i) break;
- }
- }
- for (i = 0; i < MAX_KUBI -1; i++)
- {
- int j,tmp;
- for (j = i; j < MAX_KUBI; j++)
- {
- if (r_info[kubi_r_idx[i]].level > r_info[kubi_r_idx[j]].level)
- {
- tmp = kubi_r_idx[i];
- kubi_r_idx[i] = kubi_r_idx[j];
- kubi_r_idx[j] = tmp;
- }
- }
- }
-
- p_ptr->inside_battle = TRUE;
- while (1)
- {
- today_mon = get_mon_num(3);
- r_ptr = &r_info[today_mon];
-
- if (r_ptr->flags1 & RF1_UNIQUE) continue;
- if (r_ptr->flags2 & (RF2_MULTIPLY)) continue;
- if (!(r_ptr->flags9 & RF9_DROP_CORPSE) || !(r_ptr->flags9 & RF9_DROP_SKELETON)) continue;
- if (r_ptr->rarity > 10) continue;
- if (r_ptr->level == 0) continue;
- break;
- }
- p_ptr->inside_battle = FALSE;
+ determine_bounty_uniques();
+ determine_today_mon(FALSE);
}
else
{
extern void add_history_from_pref_line(cptr t);
extern void player_birth(void);
extern void get_max_stats(void);
+extern void determine_random_questor(quest_type *q_ptr);
extern void player_outfit(void);
extern void dump_yourself(FILE *fff);
/* dungeon.c */
extern void leave_quest_check(void);
extern void extract_option_vars(void);
+extern void determine_bounty_uniques(void);
+extern void determine_today_mon(bool conv_old);
extern void play_game(bool new_game);
extern bool psychometry(void);
extern void leave_level(int level);
extern bool monster_can_enter(int y, int x, monster_race *r_ptr);
extern bool are_enemies(monster_type *m_ptr1, monster_type *m_ptr2);
extern bool monster_living(monster_race *r_ptr);
+extern bool no_questor_or_bounty_uniques(int r_idx);
/* monster2.c */
if (z_older_than(10, 0, 3))
{
- get_mon_num_prep(NULL, NULL);
- for (i = 0; i < MAX_KUBI; i++)
- {
- monster_race *r_ptr;
- while (1)
- {
- int j;
-
- kubi_r_idx[i] = get_mon_num(MAX_DEPTH - 1);
- r_ptr = &r_info[kubi_r_idx[i]];
-
- if(!(r_ptr->flags1 & RF1_UNIQUE)) continue;
-
- if(!(r_ptr->flags9 & RF9_DROP_CORPSE)) continue;
-
- if(r_ptr->flags6 & RF6_SPECIAL) continue;
-
- for (j = 0; j < i; j++)
- if (kubi_r_idx[i] == kubi_r_idx[j])break;
+ determine_bounty_uniques();
- if (j == i) break;
- }
- }
- for (i = 0; i < MAX_KUBI -1; i++)
- {
- int j,tmp;
- for (j = i; j < MAX_KUBI; j++)
- {
- if (r_info[kubi_r_idx[i]].level > r_info[kubi_r_idx[j]].level)
- {
- tmp = kubi_r_idx[i];
- kubi_r_idx[i] = kubi_r_idx[j];
- kubi_r_idx[j] = tmp;
- }
- }
- }
for (i = 0; i < MAX_KUBI; i++)
{
- if(!r_info[kubi_r_idx[i]].max_num)
- kubi_r_idx[i] += 10000;
+ /* Is this bounty unique already dead? */
+ if (!r_info[kubi_r_idx[i]].max_num) kubi_r_idx[i] += 10000;
}
}
else
if (z_older_than(10,0,3))
{
- monster_race *r_ptr;
-
- while (1)
- {
- today_mon = get_mon_num(MAX(max_dlv[DUNGEON_ANGBAND], 3));
- r_ptr = &r_info[today_mon];
-
- if (r_ptr->flags1 & RF1_UNIQUE) continue;
- if (r_ptr->flags2 & (RF2_MULTIPLY)) continue;
- if (!(r_ptr->flags9 & RF9_DROP_CORPSE) || !(r_ptr->flags9 & RF9_DROP_SKELETON)) continue;
- if (r_ptr->level < MIN(max_dlv[DUNGEON_ANGBAND], 40)) continue;
- if (r_ptr->rarity > 10) continue;
- if (r_ptr->level == 0) continue;
- break;
- }
-
- p_ptr->today_mon = 0;
+ determine_today_mon(TRUE);
}
else
{
if ((quest[i].type == QUEST_TYPE_RANDOM) && (!quest[i].r_idx))
{
- int r_idx;
- while (1)
- {
- monster_race *r_ptr;
-
- /*
- * Random monster 5 - 10 levels out of depth
- * (depending on level)
- */
- r_idx = get_mon_num(quest[i].level + 5 + randint1(quest[i].level / 10));
- r_ptr = &r_info[r_idx];
-
- if(!(r_ptr->flags1 & RF1_UNIQUE)) continue;
-
- if(r_ptr->flags6 & RF6_SPECIAL) continue;
-
- if(r_ptr->flags7 & RF7_FRIENDLY) continue;
-
- if(r_ptr->flags7 & RF7_AQUATIC) continue;
-
- if(r_ptr->flags8 & RF8_WILD_ONLY) continue;
-
- /*
- * Accept monsters that are 2 - 6 levels
- * out of depth depending on the quest level
- */
- if (r_ptr->level > (quest[i].level + (quest[i].level / 20))) break;
- }
-
- quest[i].r_idx = r_idx;
+ determine_random_questor(&quest[i]);
}
/* Load quest item index */
else
return TRUE;
}
+
+
+/*
+ * Is this monster declined to be questor or bounty?
+ */
+bool no_questor_or_bounty_uniques(int r_idx)
+{
+ switch (r_idx)
+ {
+ /*
+ * Decline them to be questor or bounty because they use
+ * special motion "split and combine"
+ */
+ case MON_BANORLUPART:
+ case MON_BANOR:
+ case MON_LUPART:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}