1 /**
2  * @file
3  * @brief Initializing non-player-related parts of a new game.
4 **/
5 /* TODO: 'you' shouldn't occur here.
6  *       Some of these might fit better elsewhere.
7  */
8 
9 #include "AppHdr.h"
10 
11 #include "mpr.h"
12 #include "ng-init.h"
13 
14 #include "branch.h"
15 #include "describe.h"
16 #include "dungeon.h"
17 #include "end.h"
18 #include "item-name.h"
19 #include "libutil.h"
20 #include "maps.h"
21 #include "ng-init-branches.h"
22 #include "random.h"
23 #include "religion.h"
24 #include "state.h"
25 #include "stringutil.h"
26 #include "tag-version.h"
27 #include "unicode.h"
28 
29 #ifdef DEBUG_DIAGNOSTICS
30 #define DEBUG_TEMPLES
31 #endif
32 
_random_potion_description()33 static uint8_t _random_potion_description()
34 {
35     int desc;
36 
37     desc = random2(PDQ_NQUALS * PDC_NCOLOURS);
38 
39     if (coinflip())
40         desc %= PDC_NCOLOURS;
41 
42     // nature and colour correspond to primary and secondary in
43     // item-name.cc.
44 
45 #if TAG_MAJOR_VERSION == 34
46     if (PCOLOUR(desc) == PDC_CLEAR) // only water can be clear, re-roll
47         return _random_potion_description();
48 #endif
49 
50     return desc;
51 }
52 
53 // Determine starting depths of branches.
initialise_branch_depths()54 void initialise_branch_depths()
55 {
56     root_branch = BRANCH_DUNGEON;
57 
58     // XXX: Should this go elsewhere?
59     branch_bribe.init(0);
60 
61     for (branch_iterator it; it; ++it)
62         brentry[it->id].clear();
63 
64     if (crawl_state.game_is_sprint())
65     {
66         brdepth.init(-1);
67         brdepth[BRANCH_DUNGEON] = 1;
68         return;
69     }
70 
71     for (int branch = 0; branch < NUM_BRANCHES; ++branch)
72     {
73         const Branch *b = &branches[branch];
74         ASSERT(b->id == branch);
75     }
76 
77     initialise_brentry();
78 }
79 
_use_overflow_temple(vector<god_type> temple_gods)80 static void _use_overflow_temple(vector<god_type> temple_gods)
81 {
82     CrawlVector &overflow_temples
83         = you.props[OVERFLOW_TEMPLES_KEY].get_vector();
84 
85     const unsigned int level = random_range(MIN_OVERFLOW_LEVEL,
86                                             MAX_OVERFLOW_LEVEL);
87 
88     // List of overflow temples on this level.
89     CrawlVector &level_temples = overflow_temples[level - 1].get_vector();
90 
91     CrawlHashTable temple;
92 
93     CrawlVector &gods = temple[TEMPLE_GODS_KEY].new_vector(SV_BYTE);
94 
95     for (unsigned int i = 0; i < temple_gods.size(); i++)
96         gods.push_back((char) temple_gods[i]);
97 
98     level_temples.push_back(temple);
99 }
100 
101 // Determine which altars go into the Ecumenical Temple, which go into
102 // overflow temples, and on what level the overflow temples are.
initialise_temples()103 void initialise_temples()
104 {
105     //////////////////////////////////////////
106     // First determine main temple map to use.
107     level_id ecumenical(BRANCH_TEMPLE, 1);
108 
109     map_def *main_temple = nullptr;
110     for (int i = 0; i < 10; i++)
111     {
112         int altar_count = 0;
113 
114         main_temple
115             = const_cast<map_def*>(random_map_for_place(ecumenical, false));
116 
117         if (main_temple == nullptr)
118             end(1, false, "No temples?!");
119 
120         if (main_temple->has_tag("temple_variable"))
121         {
122             vector<int> sizes;
123             for (const auto &tag : main_temple->get_tags())
124             {
125                 if (starts_with(tag, "temple_altars_"))
126                 {
127                     sizes.push_back(
128                         atoi(tag_without_prefix(tag,
129                                                 "temple_altars_").c_str()));
130                 }
131             }
132             if (sizes.empty())
133             {
134                 mprf(MSGCH_ERROR,
135                      "Temple %s set as variable but has no sizes.",
136                      main_temple->name.c_str());
137                 main_temple = nullptr;
138                 continue;
139             }
140             altar_count =
141                 you.props[TEMPLE_SIZE_KEY].get_int() =
142                     sizes[random2(sizes.size())];
143         }
144 
145         dgn_map_parameters mp(make_stringf("temple_altars_%d", altar_count));
146 
147         // Without all this find_glyph() returns 0.
148         string err;
149         main_temple->load();
150         main_temple->reinit();
151         err = main_temple->run_lua(true);
152 
153         if (!err.empty())
154         {
155             mprf(MSGCH_ERROR, "Temple %s: %s", main_temple->name.c_str(),
156                  err.c_str());
157             main_temple = nullptr;
158             you.props.erase(TEMPLE_SIZE_KEY);
159             continue;
160         }
161 
162         main_temple->fixup();
163         err = main_temple->resolve();
164 
165         if (!err.empty())
166         {
167             mprf(MSGCH_ERROR, "Temple %s: %s", main_temple->name.c_str(),
168                  err.c_str());
169             main_temple = nullptr;
170             you.props.erase(TEMPLE_SIZE_KEY);
171             continue;
172         }
173         break;
174     }
175 
176     if (main_temple == nullptr)
177         end(1, false, "No valid temples.");
178 
179     you.props[TEMPLE_MAP_KEY] = main_temple->name;
180 
181     const vector<coord_def> altar_coords
182         = main_temple->find_glyph('B');
183     const unsigned int main_temple_size = altar_coords.size();
184 
185     if (main_temple_size == 0)
186     {
187         end(1, false, "Main temple '%s' has no altars",
188             main_temple->name.c_str());
189     }
190 
191 #ifdef DEBUG_TEMPLES
192     mprf(MSGCH_DIAGNOSTICS, "Chose main temple %s, size %u",
193          main_temple->name.c_str(), main_temple_size);
194 #endif
195 
196     ///////////////////////////////////
197     // Now set up the overflow temples.
198 
199     vector<god_type> god_list = temple_god_list();
200     shuffle_array(god_list);
201 
202     vector<god_type> overflow_gods;
203 
204     while (god_list.size() > main_temple_size)
205     {
206         overflow_gods.push_back(god_list.back());
207         god_list.pop_back();
208     }
209 
210 #ifdef DEBUG_TEMPLES
211     mprf(MSGCH_DIAGNOSTICS, "%u overflow altars", (unsigned int)overflow_gods.size());
212 #endif
213 
214     you.props.erase(TEMPLE_GODS_KEY);      // shouldn't be set normally, but
215     you.props.erase(OVERFLOW_TEMPLES_KEY); // may be in tests
216     CrawlVector &temple_gods
217         = you.props[TEMPLE_GODS_KEY].new_vector(SV_BYTE);
218 
219     for (unsigned int i = 0; i < god_list.size(); i++)
220         temple_gods.push_back((char) god_list[i]);
221 
222     CrawlVector &overflow_temples
223         = you.props[OVERFLOW_TEMPLES_KEY].new_vector(SV_VEC);
224     overflow_temples.resize(MAX_OVERFLOW_LEVEL);
225 
226     // Count god overflow temple weights.
227     int overflow_weights[NUM_GODS + 1];
228     overflow_weights[0] = 0;
229 
230     for (unsigned int i = 1; i < NUM_GODS; i++)
231     {
232         string mapname = make_stringf("temple_overflow_generic_%d", i);
233         mapref_vector maps = find_maps_for_tag(mapname);
234         if (!maps.empty())
235         {
236             int chance = 0;
237             for (auto map : maps)
238             {
239                 // XXX: this should handle level depth better
240                 chance += map->weight(level_id(BRANCH_DUNGEON,
241                                                MAX_OVERFLOW_LEVEL));
242             }
243             overflow_weights[i] = chance;
244         }
245         else
246             overflow_weights[i] = 0;
247     }
248 
249     // Check for temple_overflow vaults that specify certain gods.
250     mapref_vector maps;
251     // the >1 range is based on previous code; 1-altar temple_overflow maps
252     // are placed by the next part, though their weight is not used here. There
253     // are currently no such vaults with more than 3 altars, but there's not
254     // much cost to checking a few higher.
255     for (int num = 2; num <= 5; num++)
256     {
257         mapref_vector num_maps = find_maps_for_tag(
258             make_stringf("temple_overflow_%d", num));
259         maps.insert(maps.end(), num_maps.begin(), num_maps.end());
260     }
261 
262     for (const map_def *map : maps)
263     {
264         if (overflow_gods.size() < 2)
265             break;
266         unsigned int num = 0;
267         vector<god_type> this_temple_gods;
268         for (const auto &tag : map->get_tags())
269         {
270             if (!starts_with(tag, "temple_overflow_"))
271                 continue;
272             string temple_tag = tag_without_prefix(tag, "temple_overflow_");
273             if (temple_tag.empty())
274             {
275                 mprf(MSGCH_ERROR, "Malformed temple tag '%s' in map %s",
276                     tag.c_str(), map->name.c_str());
277                 continue;
278             }
279             int test_num;
280             if (parse_int(temple_tag.c_str(), test_num) && test_num > 0)
281                 num = test_num;
282             else
283             {
284                 replace(temple_tag.begin(), temple_tag.end(), '_', ' ');
285                 god_type this_god = str_to_god(temple_tag);
286                 if (this_god == GOD_NO_GOD)
287                 {
288                     mprf(MSGCH_ERROR, "Malformed temple tag '%s' in map %s",
289                         tag.c_str(), map->name.c_str());
290                     continue;
291                 }
292                 this_temple_gods.push_back(this_god);
293             }
294             if (num == 0)
295             {
296                 if (this_temple_gods.size() > 0)
297                 {
298                     mprf(MSGCH_ERROR,
299                         "Map %s has temple_overflow_god tags but no count tag",
300                         map->name.c_str());
301                 }
302                 continue;
303             }
304         }
305         // there is one vault that currently triggers this, where it allows
306         // one of two specified gods on a particular altar. This code won't
307         // handle (or error) on that case right now.
308         if (num != this_temple_gods.size())
309             continue;
310 
311         // does this temple place only gods that we need to place?
312         bool ok = true;
313         for (auto god : this_temple_gods)
314             if (count(overflow_gods.begin(), overflow_gods.end(), god) == 0)
315             {
316                 ok = false;
317                 break;
318             }
319         if (!ok)
320             continue;
321         // finally: this overflow vault will place a subset of our current
322         // overflow list. Do we actually place it?
323         // TODO: The weight calculation here is kind of odd, though based on
324         // what it is directly replacing. It should sum all compatible
325         // maps first. But, the end result of this choice isn't a map anyways...
326         // More generally, I wonder if this list should be shuffled before this
327         // step, so that it's not prioritizing smaller vaults?
328         int chance = map->weight(level_id(BRANCH_DUNGEON,
329                                            MAX_OVERFLOW_LEVEL));
330         if (x_chance_in_y(chance, overflow_weights[num] + chance))
331         {
332             vector<god_type> new_overflow_gods;
333             for (auto god : overflow_gods)
334                 if (count(this_temple_gods.begin(), this_temple_gods.end(), god) == 0)
335                     new_overflow_gods.push_back(god);
336             _use_overflow_temple(this_temple_gods);
337 
338             overflow_gods = new_overflow_gods;
339         }
340     }
341 
342     // NOTE: The overflow temples don't have to contain only one
343     // altar; they can contain any number of altars, so long as there's
344     // at least one vault definition with the tag "overflow_temple_num"
345     // (where "num" is the number of altars).
346     for (unsigned int i = 0, size = overflow_gods.size(); i < size; i++)
347     {
348         unsigned int remaining_size = size - i;
349         // At least one god.
350         vector<god_type> this_temple_gods;
351         this_temple_gods.push_back(overflow_gods[i]);
352 
353         // Maybe place a larger overflow temple.
354         if (remaining_size > 1 && one_chance_in(remaining_size + 1))
355         {
356             vector<pair<unsigned int, int> > num_weights;
357             unsigned int num_gods = 1;
358 
359             // Randomly choose from the sizes which have maps.
360             for (unsigned int j = 2; j <= remaining_size; j++)
361                 if (overflow_weights[j] > 0)
362                     num_weights.emplace_back(j, overflow_weights[j]);
363 
364             if (!num_weights.empty())
365                 num_gods = *(random_choose_weighted(num_weights));
366 
367             // Add any extra gods (the first was added already).
368             for (; num_gods > 1; i++, num_gods--)
369                 this_temple_gods.push_back(overflow_gods[i + 1]);
370         }
371 
372         _use_overflow_temple(this_temple_gods);
373     }
374 }
375 
initialise_item_descriptions()376 void initialise_item_descriptions()
377 {
378     // Must remember to check for already existing colours/combinations.
379     you.item_description.init(255);
380 
381     // The order here must match that of IDESC in describe.h
382     const int max_item_number[6] = { NUM_WANDS,
383                                      NUM_POTIONS,
384                                      NUM_SCROLLS,
385                                      NUM_JEWELLERY,
386                                      NUM_SCROLLS,
387                                      NUM_STAVES };
388 
389     for (int i = 0; i < NUM_IDESC; i++)
390     {
391         // Only loop until NUM_WANDS etc.
392         for (int j = 0; j < max_item_number[i]; j++)
393         {
394             // Don't override predefines
395             if (you.item_description[i][j] != 255)
396                 continue;
397 
398             // Pick a new description until it's good.
399             while (true)
400             {
401                 switch (i)
402                 {
403                 case IDESC_WANDS: // wands
404                     you.item_description[i][j] = random2(NDSC_WAND_PRI
405                                                          * NDSC_WAND_SEC);
406                     if (coinflip())
407                         you.item_description[i][j] %= NDSC_WAND_PRI;
408                     break;
409 
410                 case IDESC_POTIONS: // potions
411                     you.item_description[i][j] = _random_potion_description();
412                     break;
413 
414 
415 #if TAG_MAJOR_VERSION == 34
416                 case IDESC_SCROLLS_II: // unused but validated
417 #endif
418                 case IDESC_SCROLLS: // scrolls: random seed for the name
419                 {
420                     // this is very weird and probably a linleyism.
421                     const int seed_1 = random2(151); // why 151?
422                     const int seed_2 = random2(151);
423                     const int seed_3 = OBJ_SCROLLS; // yes, really
424                     you.item_description[i][j] =   seed_1
425                                                 | (seed_2 << 8)
426                                                 | (seed_3 << 16);
427                     break;
428                 }
429 
430                 case IDESC_RINGS: // rings and amulets
431                     you.item_description[i][j] = random2(NDSC_JEWEL_PRI
432                                                          * NDSC_JEWEL_SEC);
433                     if (coinflip())
434                         you.item_description[i][j] %= NDSC_JEWEL_PRI;
435                     break;
436 
437                 case IDESC_STAVES: // staves
438                     you.item_description[i][j] = random2(NDSC_STAVE_PRI
439                                                          * NDSC_STAVE_SEC);
440                     break;
441                 }
442 
443                 bool is_ok = true;
444 
445                 // Test whether we've used this description before.
446                 // Don't have p < j because some are preassigned.
447                 for (int p = 0; p < max_item_number[i]; p++)
448                 {
449                     if (p == j)
450                         continue;
451 
452                     if (you.item_description[i][p] == you.item_description[i][j])
453                     {
454                         is_ok = false;
455                         break;
456                     }
457                 }
458                 if (is_ok)
459                     break;
460             }
461         }
462     }
463 }
464 
fix_up_jiyva_name()465 void fix_up_jiyva_name()
466 {
467     you.jiyva_second_name = make_name(rng::get_uint32(), MNAME_JIYVA);
468     ASSERT(you.jiyva_second_name[0] == 'J');
469 }
470