diff options
Diffstat (limited to 'src/q_rand.cc')
-rw-r--r-- | src/q_rand.cc | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/q_rand.cc b/src/q_rand.cc index 6d8f7e49..17774204 100644 --- a/src/q_rand.cc +++ b/src/q_rand.cc @@ -1,9 +1,166 @@ #include "q_rand.h" #include "hooks.h" #include "util.hpp" +#include "messages.h" static int randquest_hero[] = { 20, 13, 15, 16, 9, 17, 18, 8, -1 }; +/* Possible number(and layout) or random quests */ +#define MAX_RANDOM_QUESTS_TYPES ((8 * 3) + (8 * 1)) +static int random_quests_types[MAX_RANDOM_QUESTS_TYPES] = +{ + 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */ + 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */ + 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */ + 20, 13, 15, 16, 9, 17, 18, 8, /* Hero Sword Quest */ +}; + +/* Enforce OoD monsters until this level */ +#define RQ_LEVEL_CAP 49 + +void initialize_random_quests(int n) +{ + int step, lvl, i, k; + int old_type = dungeon_type; + + /* Zero out everything first */ + for (i = 0; i < MAX_RANDOM_QUEST; i++) random_quests[i].type = 0; + + /* Factor dlev value by 1000 to keep precision */ + step = (98 * 1000) / n; + + lvl = step / 2; + + quest[QUEST_RANDOM].status = QUEST_STATUS_TAKEN; + + for (i = 0; i < n; i++) + { + monster_race *r_ptr = &r_info[2]; + + int rl = (lvl / 1000) + 1; + + int min_level; + + int tries = 5000; + + random_quest *q_ptr = &random_quests[rl]; + + int j; + + /* Find the appropriate dungeon */ + for (j = 0; j < max_d_idx; j++) + { + dungeon_info_type *d_ptr = &d_info[j]; + + if (!(d_ptr->flags1 & DF1_PRINCIPAL)) continue; + + if ((d_ptr->mindepth <= rl) && (rl <= d_ptr->maxdepth)) + { + dungeon_type = j; + break; + } + } + + q_ptr->type = random_quests_types[rand_int(MAX_RANDOM_QUESTS_TYPES)]; + + /* XXX XXX XXX Try until valid choice is found */ + while (tries) + { + bool_ ok; + + tries--; + + /* Random monster 5 - 10 levels out of depth */ + q_ptr->r_idx = get_mon_num(rl + 4 + randint(6)); + + if (!q_ptr->r_idx) continue; + + r_ptr = &r_info[q_ptr->r_idx]; + + /* Accept only monsters that can be generated */ + if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue; + if (r_ptr->flags9 & RF9_NEVER_GENE) continue; + + /* Accept only monsters that are not breeders */ + if (r_ptr->flags4 & RF4_MULTIPLY) continue; + + /* Forbid joke monsters */ + if (r_ptr->flags8 & RF8_JOKEANGBAND) continue; + + /* Accept only monsters that are not friends */ + if (r_ptr->flags7 & RF7_PET) continue; + + /* Refuse nazguls */ + if (r_ptr->flags7 & RF7_NAZGUL) continue; + + /* Accept only monsters that are not good */ + if (r_ptr->flags3 & RF3_GOOD) continue; + + /* If module says a monster race is friendly, then skip */ + if (modules[game_module_idx].race_status != NULL) + { + s16b *status = (*modules[game_module_idx].race_status)(q_ptr->r_idx); + if ((status != NULL) && (*status >= 0)) + { + continue; + } + } + + /* Assume no explosion attacks */ + ok = TRUE; + + /* Reject monsters with exploding attacks */ + for (k = 0; k < 4; k++) + { + if (r_ptr->blow[k].method == RBM_EXPLODE) ok = FALSE; + } + if (!ok) continue; + + /* No mutliple uniques */ + if ((r_ptr->flags1 & RF1_UNIQUE) && + ((q_ptr->type != 1) || (r_ptr->max_num == -1))) continue; + + /* No single non uniques */ + if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (q_ptr->type == 1)) continue; + + /* Level restriction */ + min_level = (rl > RQ_LEVEL_CAP) ? RQ_LEVEL_CAP : rl; + + /* Accept monsters matching the level restriction */ + if (r_ptr->level > min_level) break; + } + + /* Arg could not find anything ??? */ + if (!tries) + { + if (wizard) + { + message_add(format("Could not find quest monster on lvl %d", rl), TERM_RED); + } + q_ptr->type = 0; + } + else + { + if (r_ptr->flags1 & RF1_UNIQUE) + { + r_ptr->max_num = -1; + } + + q_ptr->done = FALSE; + + if (wizard) + { + message_add(format("Quest for %d on lvl %d", + q_ptr->r_idx, rl), TERM_RED); + } + } + + lvl += step; + } + + dungeon_type = old_type; +} + bool_ is_randhero(int level) { int i; |