1 #include "floor/fixed-map-generator.h"
2 #include "dungeon/quest.h"
3 #include "floor/floor-object.h"
4 #include "floor/floor-town.h"
5 #include "floor/floor.h"
6 #include "floor/wild.h"
8 #include "info-reader/general-parser.h"
9 #include "info-reader/parse-error-types.h"
10 #include "info-reader/random-grid-effect-types.h"
11 #include "io/tokenizer.h"
12 #include "object-enchant/apply-magic.h"
13 #include "object-enchant/artifact.h"
14 #include "object-enchant/item-apply-magic.h"
15 #include "object-enchant/object-ego.h"
16 #include "object/object-generator.h"
17 #include "object/object-kind-hook.h"
18 #include "object/object-kind.h"
19 #include "room/rooms-vault.h"
20 #include "sv-definition/sv-scroll-types.h"
21 #include "system/system-variables.h"
22 #include "view/display-main-window.h"
23 #include "world/world-object.h"
24 #include "world/world.h"
26 qtwg_type *initialize_quest_generator_type(qtwg_type *qtwg_ptr, char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x)
29 qtwg_ptr->ymin = ymin;
30 qtwg_ptr->xmin = xmin;
31 qtwg_ptr->ymax = ymax;
32 qtwg_ptr->xmax = xmax;
39 * @brief フロアの所定のマスにオブジェクトを配置する
40 * Place the object j_ptr to a grid
41 * @param floor_ptr 現在フロアへの参照ポインタ
42 * @param j_ptr オブジェクト構造体の参照ポインタ
47 static void drop_here(floor_type *floor_ptr, object_type *j_ptr, POSITION y, POSITION x)
49 OBJECT_IDX o_idx = o_pop(floor_ptr);
51 o_ptr = &floor_ptr->o_list[o_idx];
52 object_copy(o_ptr, j_ptr);
55 o_ptr->held_m_idx = 0;
56 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
57 o_ptr->next_o_idx = g_ptr->o_idx;
61 static void parse_qtw_D(player_type *player_ptr, qtwg_type *qg_ptr, char *s)
63 *qg_ptr->x = qg_ptr->xmin;
64 floor_type *floor_ptr = player_ptr->current_floor_ptr;
66 for (int i = 0; ((*qg_ptr->x < qg_ptr->xmax) && (i < len)); (*qg_ptr->x)++, s++, i++) {
67 grid_type *g_ptr = &floor_ptr->grid_array[*qg_ptr->y][*qg_ptr->x];
69 OBJECT_IDX object_index = letter[idx].object;
70 MONSTER_IDX monster_index = letter[idx].monster;
71 int random = letter[idx].random;
72 ARTIFACT_IDX artifact_index = letter[idx].artifact;
73 g_ptr->feat = conv_dungeon_feat(floor_ptr, letter[idx].feature);
74 if (init_flags & INIT_ONLY_FEATURES)
77 g_ptr->info = letter[idx].cave_info;
78 if (random & RANDOM_MONSTER) {
79 floor_ptr->monster_level = floor_ptr->base_level + monster_index;
81 place_monster(player_ptr, *qg_ptr->y, *qg_ptr->x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));
83 floor_ptr->monster_level = floor_ptr->base_level;
84 } else if (monster_index) {
85 int old_cur_num, old_max_num;
88 if (monster_index < 0) {
89 monster_index = -monster_index;
93 old_cur_num = r_info[monster_index].cur_num;
94 old_max_num = r_info[monster_index].max_num;
96 if (r_info[monster_index].flags1 & RF1_UNIQUE) {
97 r_info[monster_index].cur_num = 0;
98 r_info[monster_index].max_num = 1;
99 } else if (r_info[monster_index].flags7 & RF7_NAZGUL) {
100 if (r_info[monster_index].cur_num == r_info[monster_index].max_num) {
101 r_info[monster_index].max_num++;
105 place_monster_aux(player_ptr, 0, *qg_ptr->y, *qg_ptr->x, monster_index, (PM_ALLOW_SLEEP | PM_NO_KAGE));
107 floor_ptr->m_list[hack_m_idx_ii].smart |= SM_CLONED;
108 r_info[monster_index].cur_num = old_cur_num;
109 r_info[monster_index].max_num = old_max_num;
113 if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP)) {
114 floor_ptr->object_level = floor_ptr->base_level + object_index;
117 * Random trap and random treasure defined
118 * 25% chance for trap and 75% chance for object
120 if (randint0(100) < 75) {
121 place_object(player_ptr, *qg_ptr->y, *qg_ptr->x, 0L);
123 place_trap(player_ptr, *qg_ptr->y, *qg_ptr->x);
126 floor_ptr->object_level = floor_ptr->base_level;
127 } else if (random & RANDOM_OBJECT) {
128 floor_ptr->object_level = floor_ptr->base_level + object_index;
129 if (randint0(100) < 75)
130 place_object(player_ptr, *qg_ptr->y, *qg_ptr->x, 0L);
131 else if (randint0(100) < 80)
132 place_object(player_ptr, *qg_ptr->y, *qg_ptr->x, AM_GOOD);
134 place_object(player_ptr, *qg_ptr->y, *qg_ptr->x, AM_GOOD | AM_GREAT);
136 floor_ptr->object_level = floor_ptr->base_level;
137 } else if (random & RANDOM_TRAP) {
138 place_trap(player_ptr, *qg_ptr->y, *qg_ptr->x);
139 } else if (letter[idx].trap) {
140 g_ptr->mimic = g_ptr->feat;
141 g_ptr->feat = conv_dungeon_feat(floor_ptr, letter[idx].trap);
142 } else if (object_index) {
143 object_type tmp_object;
144 object_type *o_ptr = &tmp_object;
145 object_prep(o_ptr, object_index);
146 if (o_ptr->tval == TV_GOLD) {
147 coin_type = object_index - OBJ_GOLD_LIST;
148 make_gold(floor_ptr, o_ptr);
152 apply_magic(player_ptr, o_ptr, floor_ptr->base_level, AM_NO_FIXED_ART | AM_GOOD);
153 drop_here(floor_ptr, o_ptr, *qg_ptr->y, *qg_ptr->x);
156 if (artifact_index) {
157 if (a_info[artifact_index].cur_num) {
158 KIND_OBJECT_IDX k_idx = lookup_kind(TV_SCROLL, SV_SCROLL_ACQUIREMENT);
160 object_type *q_ptr = &forge;
162 object_prep(q_ptr, k_idx);
163 drop_here(floor_ptr, q_ptr, *qg_ptr->y, *qg_ptr->x);
165 if (create_named_art(player_ptr, artifact_index, *qg_ptr->y, *qg_ptr->x))
166 a_info[artifact_index].cur_num = 1;
170 g_ptr->special = letter[idx].special;
174 static bool parse_qtw_QQ(char **zz, int num, quest_type *q_ptr)
179 if ((init_flags & INIT_ASSIGN) == 0)
183 artifact_type *a_ptr;
186 return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
188 q_ptr->type = (QUEST_TYPE)atoi(zz[2]);
189 q_ptr->num_mon = (MONSTER_NUMBER)atoi(zz[3]);
190 q_ptr->cur_num = (MONSTER_NUMBER)atoi(zz[4]);
191 q_ptr->max_num = (MONSTER_NUMBER)atoi(zz[5]);
192 q_ptr->level = (DEPTH)atoi(zz[6]);
193 q_ptr->r_idx = (IDX)atoi(zz[7]);
194 q_ptr->k_idx = (IDX)atoi(zz[8]);
195 q_ptr->dungeon = (DUNGEON_IDX)atoi(zz[9]);
198 q_ptr->flags = atoi(zz[10]);
200 r_ptr = &r_info[q_ptr->r_idx];
201 if (r_ptr->flags1 & RF1_UNIQUE)
202 r_ptr->flags1 |= RF1_QUESTOR;
204 a_ptr = &a_info[q_ptr->k_idx];
205 a_ptr->gen_flags |= TRG_QUESTITEM;
210 * @brief 固定マップ (クエスト&街&広域マップ)をフロアに生成する
211 * Parse a sub-file of the "extra info"
212 * @param player_ptr プレーヤーへの参照ポインタ
222 errr generate_fixed_map_floor(player_type *player_ptr, qtwg_type *qtwg_ptr, process_dungeon_file_pf parse_fixed_map)
225 if (!qtwg_ptr->buf[0])
228 if (iswspace(qtwg_ptr->buf[0]))
231 if (qtwg_ptr->buf[0] == '#')
234 if (qtwg_ptr->buf[1] != ':')
237 if (qtwg_ptr->buf[0] == '%')
238 return (*parse_fixed_map)(player_ptr, qtwg_ptr->buf + 2, qtwg_ptr->ymin, qtwg_ptr->xmin, qtwg_ptr->ymax, qtwg_ptr->xmax);
240 /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid */
241 if (qtwg_ptr->buf[0] == 'F')
242 return parse_line_feature(player_ptr->current_floor_ptr, qtwg_ptr->buf);
244 if (qtwg_ptr->buf[0] == 'D') {
245 char *s = qtwg_ptr->buf + 2;
246 if (init_flags & INIT_ONLY_BUILDINGS)
249 parse_qtw_D(player_ptr, qtwg_ptr, s);
254 if (qtwg_ptr->buf[0] == 'Q') {
255 if (qtwg_ptr->buf[2] == '$')
258 int num = tokenize(qtwg_ptr->buf + _(2, 3), 33, zz, 0);
260 return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
263 q_ptr = &(quest[atoi(zz[0])]);
264 if (parse_qtw_QQ(zz, num, q_ptr))
267 if (zz[1][0] == 'R') {
268 if (init_flags & INIT_ASSIGN) {
270 IDX idx, reward_idx = 0;
272 for (idx = 2; idx < num; idx++) {
273 IDX a_idx = (IDX)atoi(zz[idx]);
276 if (a_info[a_idx].cur_num > 0)
284 q_ptr->k_idx = reward_idx;
285 a_info[reward_idx].gen_flags |= TRG_QUESTITEM;
287 q_ptr->type = QUEST_TYPE_KILL_ALL;
294 if (zz[1][0] == 'N') {
295 if (init_flags & (INIT_ASSIGN | INIT_SHOW_TEXT | INIT_NAME_ONLY)) {
296 strcpy(q_ptr->name, zz[2]);
302 if (zz[1][0] == 'T') {
303 if (init_flags & INIT_SHOW_TEXT) {
304 strcpy(quest_text[quest_text_line], zz[2]);
314 if (qtwg_ptr->buf[0] == 'W')
315 return parse_line_wilderness(player_ptr, qtwg_ptr->buf, qtwg_ptr->xmin, qtwg_ptr->xmax, qtwg_ptr->y, qtwg_ptr->x);
317 if (qtwg_ptr->buf[0] == 'P') {
318 if (init_flags & INIT_CREATE_DUNGEON) {
319 if (tokenize(qtwg_ptr->buf + 2, 2, zz, 0) == 2) {
320 int panels_x, panels_y;
322 panels_y = (*qtwg_ptr->y / SCREEN_HGT);
323 if (*qtwg_ptr->y % SCREEN_HGT)
326 floor_type *floor_ptr = player_ptr->current_floor_ptr;
327 floor_ptr->height = panels_y * SCREEN_HGT;
328 panels_x = (*qtwg_ptr->x / SCREEN_WID);
329 if (*qtwg_ptr->x % SCREEN_WID)
332 floor_ptr->width = panels_x * SCREEN_WID;
333 panel_row_min = floor_ptr->height;
334 panel_col_min = floor_ptr->width;
336 if (floor_ptr->inside_quest) {
337 delete_monster(player_ptr, player_ptr->y, player_ptr->x);
339 POSITION py = atoi(zz[0]);
340 POSITION px = atoi(zz[1]);
344 } else if (!player_ptr->oldpx && !player_ptr->oldpy) {
345 player_ptr->oldpy = atoi(zz[0]);
346 player_ptr->oldpx = atoi(zz[1]);
354 if (qtwg_ptr->buf[0] == 'B')
355 return parse_line_building(qtwg_ptr->buf);
357 if (qtwg_ptr->buf[0] == 'M') {
358 if (tokenize(qtwg_ptr->buf + 2, 2, zz, 0) == 2) {
359 if (zz[0][0] == 'T') {
360 max_towns = (TOWN_IDX)atoi(zz[1]);
361 } else if (zz[0][0] == 'Q') {
362 max_q_idx = (QUEST_IDX)atoi(zz[1]);
363 } else if (zz[0][0] == 'R') {
364 max_r_idx = (player_race_type)atoi(zz[1]);
365 } else if (zz[0][0] == 'K') {
366 max_k_idx = (KIND_OBJECT_IDX)atoi(zz[1]);
367 } else if (zz[0][0] == 'V') {
368 max_v_idx = (VAULT_IDX)atoi(zz[1]);
369 } else if (zz[0][0] == 'F') {
370 max_f_idx = (FEAT_IDX)atoi(zz[1]);
371 } else if (zz[0][0] == 'A') {
372 max_a_idx = (ARTIFACT_IDX)atoi(zz[1]);
373 } else if (zz[0][0] == 'E') {
374 max_e_idx = (EGO_IDX)atoi(zz[1]);
375 } else if (zz[0][0] == 'D') {
376 current_world_ptr->max_d_idx = (DUNGEON_IDX)atoi(zz[1]);
377 } else if (zz[0][0] == 'O') {
378 current_world_ptr->max_o_idx = (OBJECT_IDX)atoi(zz[1]);
379 } else if (zz[0][0] == 'M') {
380 current_world_ptr->max_m_idx = (MONSTER_IDX)atoi(zz[1]);
381 } else if (zz[0][0] == 'W') {
383 current_world_ptr->max_wild_x = (POSITION)atoi(zz[1]);
386 current_world_ptr->max_wild_y = (POSITION)atoi(zz[1]);