1 // Hyperbolic Rogue -- items, monsters, walls, lands, descriptions, etc.
2 // Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
3
4 /** \file classes.cpp
5 * \brief items, monsters, walls, lands, descriptions, etc.
6 *
7 * See content.cpp for actual items, monsters, walls and lands.
8 */
9
10 #include "hyper.h"
11 namespace hr {
12
13 // --- help ---
14
15 const char *wormdes =
16 "These huge monsters normally live below the sand, but your movements have "
17 "disturbed them. They are too big to be slain with your "
18 "weapons, but you can defeat them by making them unable to move. "
19 "This also produces some Spice. They move two times slower than you.";
20
21 const char *cocytushelp =
22 "This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.";
23
24 const char *tentdes =
25 "The tentacles of Cthulhu are like sandworms, but longer. "
26 "They also withdraw one cell at a time, instead of exploding instantly.";
27
28 const char *gameboardhelp =
29 "Ever wondered how some boardgame would look on the hyperbolic plane? "
30 "I wondered about Go, so I have created this feature. Now you can try yourself!\n"
31 "Enter = pick up an item (and score), space = clear an item\n"
32 "Other keys place orbs and terrain features of various kinds\n"
33 "In the periodic editor, press 0-4 to switch walls in different ways\n"
34 ;
35
36 const char *ivydes =
37 "A huge plant growing in the Jungle. Each Ivy has many branches, "
38 "and one branch grows per each of your moves. Branches grow in a clockwise "
39 "order. The root itself is vulnerable.";
40
41 const char *slimehelp =
42 "The Alchemists produce magical potions from pools of blue and red slime. You "
43 "can go through these pools, but you cannot move from a blue pool to a red "
44 "pool, or vice versa. Pools containing items count as colorless, and "
45 "they change color to the PC's previous color when the item is picked up. "
46 "Slime beasts also have to keep to their own color, "
47 "but when they are killed, they explode, destroying items and changing "
48 "the color of the slime and slime beasts around them.";
49
50 const char *gdemonhelp =
51 "These creatures are slow, but very powerful... more powerful than you. "
52 "You need some more experience in demon fighting before you will be able to defeat them. "
53 "Even then, you will be able to slay this one, but more powerful demons will come...\n\n"
54 "Each 10 lesser demons you kill, you become powerful enough to kill all the greater "
55 "demons on the screen, effectively turning them into lesser demons.";
56
57 const char *ldemonhelp =
58 "These creatures are slow, but they often appear in large numbers.";
59
60 const char *trollhelp =
61 "A big monster from the Living Caves. A dead Troll will be reunited "
62 "with the rocks, causing some walls to grow around its body.";
63
64 EX const char *trollhelp2 =
65 " Additionally, all items around the killed Troll will be destroyed.";
66
67 const char *trollhelpX =
68 "There are several species of trolls living in the hyperbolic world. "
69 "Some of them leave this wall behind them when they die.";
70
71 const char *camelothelp =
72 "The Knights of the Round Table are the greatest warriors of these lands. "
73 "They are not very inventive with names though, as they call each of their "
74 "castles Camelot. "
75 "You are probably worthy of joining them, but they will surely give you "
76 "some quest to prove yourself...\n\n"
77 "Each castle contains a single treasure, the Holy Grail, in the center. "
78 "The radius of the Round Table is usually 28, but after you find a Holy Grail "
79 "successfully, each new castle (and each Round Table) you find will be bigger.";
80
81 const char *templehelp =
82 "The temple of Cthulhu consists of many concentric circles of columns. "
83 "You will surely encounter many Cultists there, who believe that a pilgrimage "
84 "to the inner circles will bring them closer to Cthulhu himself, and Grimoires "
85 "which surely contain many interesting secrets.\n\n"
86 "The circles in the temple of Cthulhu are actually horocycles. They are "
87 "infinite, and there is an infinite number of them.";
88
89 const char *barrierhelp =
90 "Huge, impassable walls which separate various lands.";
91
92 const char *cavehelp =
93 "This cave contains walls which are somehow living. After each turn, each cell "
94 "counts the number of living wall and living floor cells around it, and if it is "
95 "currently of a different type than the majority of cells around it, it switches. "
96 "Items count as three floor cells, and dead Trolls count as five wall cells. "
97 "Some foreign monsters also count as floor or wall cells.\n";
98
99 const char *vinehelp =
100 "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n"
101 "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.";
102
103 const char *hvinehelp =
104 "A vine is growing here... but only on a half of the cell. How is that even possible?!"
105 "Most monsters cannot move from this cell to the cell containing the other half. "
106 "Vine spirits can move only to the adjacent cells which are also adjacent to the "
107 "other half.";
108
109 const char *deadcavehelp =
110 "Somehow, this cave has not received the spark of Life yet.";
111
112 const char *foresthelp =
113 "This forest is quite dry. Beware the bushfires!\n"
114 "Trees catch fire on the next turn. The temperature of the grass cells "
115 "rises once per turn for each fire nearby, and becomes fire itself "
116 "when its temperature has risen 10 times.\n"
117 "You can also chop down the trees. Big trees take two turns to chop down.";
118
119 const char *hivehelp =
120 "The Hive is filled with Hyperbugs. They are huge insects which look a bit like "
121 "ants, a bit like bees, and a bit like roaches. "
122 "They live in circular nests, and an army of Hyperbugs will attack any intruder, "
123 "including you and enemy Hyperbugs. Will you manage to get to the "
124 "heart of such a nest, and get the precious Royal Jelly?";
125
126 const char *redrockhelp =
127 "This land contains high rock formations. Most of the valley is at level 0, "
128 "while items are found at level 3. It is impossible to gain two or more levels, "
129 "or to lose three levels, in a single move, (attacks are possible at any "
130 "difference, though). Kill Red Trolls and Rock Snakes to make a cell higher.";
131
132 const char *caribbeanhelp =
133 "This dangerous sea contains nasty sharks and pirates. ";
134
135 const char *cislandhelp =
136 "The islands of Caribbean are infinite and circular, and "
137 "the pirates probably have hidden their treasures somewhere far from the coast.";
138
139 const char *redsnakedes =
140 "Rock snakes are similar to Sandworms, but they move each turn. However, they "
141 "only move on the hexagonal cells. They are also somewhat longer than the Sandworms.";
142
143 const char *minedesc =
144 "This minefield has been created by the Bomberbirds to protect their valuable eggs. "
145 "Mines explode when they are stepped on, creating fire all around them "
146 "(this fire never expires in the Minefield). If you don't step on a mine, you "
147 "know the number of mines in cells around you. These numbers are marked with "
148 "color codes on the cells you have visited.";
149
150 const char *palacedesc =
151 "So better just to concentrate on collecting treasure. "
152 "Beware the traps, and the guards, who are hard to kill!";
153
154 const char *gatedesc =
155 "Green pressure plates open all gates in radius 3 around them. "
156 "Similarly, red pressure plates close all gates in this radius.";
157
158 const char *princessdesc =
159 "A mouse squeaks at you. It seems that it wants you to go somewhere. "
160 "That's interesting, what could you find here?\n\n"
161 "Note: in the part of the Palace that you are exploring during this "
162 "quest, the distribution of monsters, pressure plates, and items has been "
163 "changed somewhat, to make it a bit more suitable for less "
164 "experienced players. The number of monsters does not depend on the "
165 "number of Hypersian Rugs you have collected, and there are more "
166 "opening plates.\n\n"
167 "However, even with the normal distribution, it appears that it should be "
168 "always possible to reach your goal. If you want this challenge, "
169 "select it from the special game modes menu.";
170
171 const char *elemdesc =
172 "The Elemental Planes are divided into four subzones: Planes of Fire, Water, Air, and Earth. "
173 "You need to collect a Shard from each Plane to construct an Elemental Gem. "
174 "It is dangerous to collect too many Shards of the same type without constructing a Gem.";
175
176 const char *wildwestdesc =
177 "Take a revolver, kill outlaws, collect bounties.\n\n"
178 "Note: since this land is anachronistic, it is not available in normal game. "
179 "It is only available in special modes.";
180
181 const char *elecdesc =
182 "Whenever after your move there is a connection between a charged and a "
183 "grounded cell, there is a short circuit. All cells on any "
184 "path connecting a charged and a grounded cell (without repeated cells, "
185 "or two consecutive grounded/charged cells) become damaged.\n\n"
186
187 "Sandstone walls and most creatures are conductive. Great Walls are "
188 "isolators, but lands beyond them count as grounded.\n\n"
189
190 "Fulgurite, the treasure, is created when you manage to short circuit "
191 "a sandstone wall, or a Rich Metal Beast.\n\n"
192
193 "Trolls leave conductive rocks when killed, and Metal Beasts can only "
194 "be killed by electricity -- your attacks only stun them, or push "
195 "them away if already stunned.";
196
197 const char *overdesc =
198 "The Overgrown Woods are filled with mutant ivies! These plants "
199 "grow very fast. Each leaf, after being grown, can grow itself "
200 "on the next turn. However, each part is only able to grow "
201 "once in 16 turns. Outside of the Overgrown Woods, the Mutant Ivy "
202 "may grow only on hexagonal cells.\n\n"
203 "Maybe such fast growing plants could help you solve the problem "
204 "of hunger in your world? Kill the Mutant Ivies to collect Mutant Saplings.";
205
206 const char *cleardesc =
207 "A clearing in the Overgrown Woods. Obviously, this gives "
208 "the Mutant Ivies an infinite space to grow...\n\n"
209 "Mutant Fruits rot if they are not adjacent to a Mutant Ivy.";
210
211 const char *winddesc =
212 "Someone has put air fans in these plains, causing strong winds everywhere. "
213 "You think that the purpose is to harness the magical power of Air Elementals, but "
214 "you are not sure.\n\n"
215 "All cells except fans are grouped into three colors according to a pattern. "
216 "Wind blows counterclockwise around each group of cells of a single color. "
217 "Cells which are blocked by walls, or at distance at most 2 from an Air Elemental, "
218 "do not count for this.\n\n"
219 "It is illegal to move in a direction which is closer to incoming wind than to "
220 "outgoing wind. However, you can move two cells with the wind in a single turn, "
221 "and so can the birds.";
222
223 const char *warningdesc =
224 "Warnings are issued when you try to do something that appears dangerous, "
225 "like stepping on a known mine, or getting your boat destroyed by "
226 "a Kraken without having Orb of the Fish. In some cases the action "
227 "might actually be safe -- so you can ignore the warning and do it anyway, "
228 "simply by repeating the action.";
229
230 const char *hauntdesc =
231 "A dark forest filled with ghosts and graves. But there is also treasure hidden "
232 "deep within... But don't let greed make you stray from your path, as "
233 "you can get lost!\n\n"
234 "The Haunted Woods are bounded by a single equidistant curve. It is not a circle or horocycle.\n\n";
235
236 const char *bulldashdesc =
237 "Butterflies don't pursue you -- unless you get next to them, they just spin around the obstacles. "
238 "They cannot be killed conventionally, but you get treasure when a Raging Bull crashes into a Butterfly. ";
239
240 const char *prairiedesc =
241 "You can find safety in some places in the Prairie, but if you want treasures, "
242 "they can be found only on the other side of a giant herd of bulls.";
243
244 const char *cadesc =
245 "A land for people wanting to experiment with cellular automata in the HyperRogue grid. "
246 "Rules can be given on the command line; the default rules are:\n"
247 "-c07 00100000 -c06 0010000 -c17 00011000 -c16 0001100 -caprob 0.3\n"
248 "(-c0 or -c1 can be given if the same rule is to be used for hexagonal "
249 "and heptagonal cells).";
250
251 const char *huntingdesc =
252 "The Happy Hunting Ground is the place where hunting is easy; "
253 "the spirits of hunters go here after their death, if their life was deemed worthy. "
254 "You did not qualify though, so you will not ever be able to find your way to the places "
255 "where the hunter spirits and game are... "
256 "and their hunting dogs will hunt you instead!\n\n"
257 "You hope to use this to learn some "
258 "skills in fighting in open hyperbolic space, though.";
259
260 const char *terradesc =
261 "Spending 3-5 turns next to the Terracotta Warriors will cause them to awaken. "
262 "They have 7 HP, and get stunned for longer and longer time with each attack.";
263
264 const char *terraldesc =
265 "The Emperor's mausoleum. The army "
266 "of Terracotta Warriors is supposed to protect him in his "
267 "afterlife, while the traps are to protect the treasures "
268 "in the mausoleum from thieves.";
269
270 const char *arrowtrapdesc =
271 "The arrow traps will automatically launch a deadly arrow when stepped on. They are quite old though, so the arrow will "
272 "actually fly at the end of the next turn.";
273
274 const char *lavadesc =
275 "The volcanic activity in this land is extremely unstable. "
276 "Lava is too hot to walk on. It cools quickly, but another "
277 "flow will come soon...";
278
279 const char *blizzarddesc =
280 "Once in the past there lived a tribe whose prophets warned about the great blizzard that was to come and freeze the world. "
281 "They thought it was the wrath of the gods, so they put some altars, so that the gods could hear their pleas. "
282 "The mighty golems guarded those altars, making sure nobody steals the jewels, because a robbed god is a angry god. "
283 "Unfortunately winter has come (maybe because only the monks knew how to stop the golems, and they were said to had escaped earlier with some of the jewels). "
284 "The tribe has frozen to death, altars got covered with snow and ice. Only ice golems still guard them waiting for the spring.";
285
286 const char *crystaldesc =
287 "Yes, this is definitely a crystal. A very regular crystalline structure.\n\n"
288 "This land has been designed as a tool to play with various geometries, and it does not appear during a normal gameplay.";
289
290 const char *NODESC = "No description yet.";
291 const char *NODESCYET = "No description yet.";
292 const char *GENDERSWITCH = NODESC;
293
294 // --- monsters ---
295
296 EX const char *rosedesc =
297 "Each eight turns, each rosebush at distance at most 5 from you will "
298 "release a wave of alluring scent. Creatures on the frontwave "
299 "will move towards where the scent came from. Even if it causes them "
300 "to attack their friends or beautiful creatures, or move into water, fire, chasm, or thorns of the rosebush. "
301 "Ivies, Ghosts, Rock Snakes, Rose Ladies and Lords, and monsters restricted to a specific "
302 "terrain are immune to scents.";
303
304 EX const char *warpdesc =
305 "This part of the world is warped, restricting the movement somewhat. "
306 "\"Diagonal\" movement and attacking between triangular cells is not allowed. "
307 "Flash, Storms, and Freedom spells ignore this, and Ghosts can move, attack, and "
308 "be attacked diagonally.";
309
310 const char *warplanddesc =
311 "This land is warped. Ironically, the coast is completely straight...";
312
313 const char *roselanddesc =
314 "This land is filled with beautiful, but dangerous, creatures and plants.";
315
316 const char *dragondesc =
317 "Dragons are powerful monsters. They are slow, but evil, "
318 "and love to pick on creatures who are even slower than "
319 "them. They must be stopped!\n\n"
320
321 "A Dragon moves each two turns. It may attack with all its segments, "
322 "or move its whole body forwards or "
323 "backwards, it may also move a frontal part backwards. To kill a Dragon, "
324 "you need to hit each of its segments. "
325 "The head will regenerate on the "
326 "turns the Dragon is not moving, so you will usually have to hit it with "
327 "your last attack; otherwise, if the head is healthy, it may breathe "
328 "fire (at range 3), losing the hitpoint. Killing the Dragon "
329 "while still in the Dragon Chasms gives you treasure.";
330
331 const char *tortoisedesc =
332 "Galápagos is the land of Tortoises. "
333 "They are very slow, which allows the Dragons to pick on them by "
334 "stealing and eating their young. Bring the Baby Tortoises back, "
335 "but, there is a catch: the Tortoises come in many varieties, depending "
336 "on the part of Galápagos they live in -- there are 21 binary environmental "
337 "factors, and thus "
338 "2097152 varieties. You'll have to find a "
339 "Tortoise which matches the baby exactly!\n\n"
340 "Tortoises move each 3 turns, and attacks only stun them.\n\n"
341 "Bringing back a Baby Tortoise counts as 5 $$$. The more factors agree in "
342 "the given location of Galápagos, the brighter it is shown on your screen.";
343
344 const char *krakendesc =
345 "There are Krakens in your homeland, too... huge sea monsters which "
346 "could easily destroy ships. The geometry of this strange world "
347 "prevents quick movement of huge objects, "
348 "so there are no large ships, only small boats, and "
349 "hyperbolic Krakens are relatively small too. Still, you suppose they might be "
350 "the widest creatures which could still move at considerable speed...\n\n"
351
352 "Kraken heads can move only on hexagons. You need to attack all the tentacles to "
353 "kill the Kraken. A tentacle cannot attack if it has been attacked on the "
354 "same turn. When a Kraken attacks you while you are in a boat, it "
355 "destroys the boat, but does not kill you.";
356
357 const char *halloweendesc =
358 "Halloween is a special land, that is available only in the spherical "
359 "or elliptic geometry (press 'o' to switch). You play on the surface of "
360 "a jack-o'-lantern, "
361 "and have to collect as many Treats as possible. Each Treat you collect "
362 "brings new monsters to fight, and new magical powers for you. You "
363 "have to fight the monsters while effectively managing your limited "
364 "resources.";
365
366 const char *reptiledesc =
367 "These reptiles are quite strange creatures. They "
368 "spend most of their lives sleeping as floors "
369 "that other creatures can walk on. "
370 "Sometimes they wake up to hunt their prey, "
371 "but they will happily go back to sleep if they "
372 "happen to move into a hole on their way. "
373 "Your attacks do not kill the Reptiles, but "
374 "you can push and stun them.";
375
376 const char *naturedesc =
377 "This Orb allows you to grow like an Ivy. "
378 "The Ivy is always rooted in your current location; "
379 "moving among the Ivy cells will move the root. "
380 "Moving to a new location will cause the Ivy to grow "
381 ", if an Ivy could make that movement "
382 "(otherwise it breaks). "
383 "You can also target one of the cells adjacent to your ivy "
384 "(not to you) to grow or attack there.";
385
386 const char *mirroreddesc =
387 "A perfect mirror wall. It is unbreakable "
388 "and impassable "
389 "even for aethereal beings, and everything "
390 "you see inside is just an image of "
391 "the real world; you can swing your sword "
392 "at them, but that will not destroy them "
393 "in the real world. "
394 "Mirror walls reflect Mimics, lightning bolts, and "
395 "missiles perfectly.";
396
397 const char* tamebomberdesc =
398 "This bomberbird will follow you at some distance, and attack your enemies. "
399 "You can kill it to place a mine.";
400
401 const char *gargdesc =
402 "A being made of stone, who likes high buildings. It becomes normal stone when "
403 "killed, but only if next to something stable -- otherwise it falls.";
404
405 const char *lakeDesc = "Hell has these lakes everywhere... They are shaped like evil stars, and filled with burning sulphur.";
406
407 const char *thumpdesc = "A device that attracts sandworms and other enemies. You need to activate it.";
408
409 const char *twdesc = "This structure will disappear after some time.";
410
411 const char *jellydesc =
412 "Some of the Slime Beasts have decided to revolt against the color rules in the "
413 "Alchemist Lab. They have changed their shape and consistency, declared independence, and established their own Kingdom.\n\n"
414 "Jellies switch between being a wall and being a monster after every treasure you collect.";
415
416 const char *ruindesc =
417 "Once a beautiful city... but now overrun by the mighty Raiders of unknown origin.\n\n"
418 "Raiders cannot be harmed with mundane weapons, but each color has its movement restrictions.";
419
420 const char *rock_description =
421 "Shoot the Space Rocks for score. Large Rocks will split into two smaller rocks.";
422
423 #if HDR
424 enum eSlimegroup { sgNone, sgCave, sgWater, sgFloorA, sgFloorB, sgVine, sgTree };
425 #endif
426
427 #if HDR
428 // we use CF not MF to avoid confusion with MF_ movement flags
429 static const flagtype CF_NOGHOST = Flag(0);
430 static const flagtype CF_RAIDER = Flag(1);
431 static const flagtype CF_PRINCESS = Flag(2);
432 static const flagtype CF_MIMIC = Flag(3);
433 static const flagtype CF_GOK = Flag(4);
434 static const flagtype CF_NONLIVING = Flag(5);
435 static const flagtype CF_METAL = Flag(6);
436 static const flagtype CF_STUNNABLE = Flag(7);
437 static const flagtype CF_HP = Flag(8);
438 static const flagtype CF_MOUNTABLE = Flag(9);
439 static const flagtype CF_FRIENDLY = Flag(10);
440 static const flagtype CF_PLAYER = Flag(11);
441 static const flagtype CF_BUG = Flag(12);
442 static const flagtype CF_IVY = Flag(13);
443 static const flagtype CF_PART = Flag(14);
444 static const flagtype CF_MUTANTIVY = Flag(15);
445 static const flagtype CF_ANYIVY = Flag(16);
446 static const flagtype CF_BULLET = Flag(17);
447 static const flagtype CF_DEMON = Flag(18);
448 static const flagtype CF_WORM = Flag(19);
449 static const flagtype CF_WITCH = Flag(20);
450 static const flagtype CF_BIRD = Flag(21);
451 static const flagtype CF_SLOWMOVER = Flag(22);
452 static const flagtype CF_MAGNETIC = Flag(23);
453 static const flagtype CF_SWITCH = Flag(24);
454 static const flagtype CF_GHOST = Flag(25);
455 static const flagtype CF_SHARK = Flag(26);
456 static const flagtype CF_SLIME = Flag(27);
457 static const flagtype CF_DRAGON = Flag(28);
458 static const flagtype CF_KRAKEN = Flag(29);
459 static const flagtype CF_NOBLOW = Flag(30);
460 static const flagtype CF_MULTITILE = Flag(31);
461 static const flagtype CF_LEADER = Flag(32);
462 static const flagtype CF_FLYING = Flag(33);
463 static const flagtype CF_ATTACK_THRU_VINE = Flag(34);
464 static const flagtype CF_ATTACK_NONADJACENT = Flag(35);
465 static const flagtype CF_NOHIGHLIGHT = Flag(36);
466 static const flagtype CF_INACTIVE = Flag(37);
467 static const flagtype CF_UNARMED = Flag(38);
468 static const flagtype CF_IGNORE_PLATE = Flag(39);
469 static const flagtype CF_BULL = Flag(40);
470 static const flagtype CF_TROLL = Flag(41);
471 static const flagtype CF_IGNORE_SMELL = Flag(42);
472 static const flagtype CF_RATLING = Flag(43);
473 static const flagtype CF_POWER = Flag(44);
474 static const flagtype CF_GHOSTMOVER = Flag(45);
475 static const flagtype CF_TECHNICAL = Flag(46);
476 static const flagtype CF_MOVED = Flag(47);
477 static const flagtype CF_FACING = Flag(48);
478 static const flagtype CF_FACE_UP = Flag(49);
479 static const flagtype CF_FACE_SIDE = Flag(50);
480 static const flagtype CF_HIGH_THREAT = Flag(51);
481 static const flagtype CF_SPAM = Flag(52);
482
483 enum eMonster {
484 #define MONSTER(a,b,c,d,e,f,g,h) d,
485 #include "content.cpp"
486 motypes
487 };
488
489 struct monstertype {
490 char glyph;
491 color_t color;
492 const char *name;
493 flagtype flags;
494 enum eMonster mgroup;
495 const char *help;
496 };
497 #endif
498
499 EX monstertype minf[motypes] = {
500 #define MONSTER(a,b,c,d,e,f,g,h) {a,b,c,e,g,h},
501 #include "content.cpp"
502 };
503
504 #if HDR
505 #define NUM_GS 8
506 struct genderswitch_t {
507 int gender;
508 eMonster m;
509 const char *name;
510 const char *desc;
511 };
512 #endif
513
514 EX genderswitch_t genderswitch[NUM_GS] = {
515 { GEN_F, moFalsePrincess, "False Princess",
516 "Don't be fooled by this red-haired girl, or you will be stabbed if you come too close!"},
517 { GEN_M, moFalsePrincess, "False Prince",
518 "Don't be fooled by this red-haired boy, or you will be stabbed if you come too close!"},
519 { GEN_F, moRoseLady, "Rose Lady",
520 "This false princess is immune to the alluring scent of roses."},
521 { GEN_M, moRoseLady, "Rose Lord",
522 "This false prince is immune to the alluring scent of roses."},
523 { GEN_F, moRoseBeauty, "Rose Beauty",
524 "She has flowers in her long fair hair. You could not bring yourself to attack such a beautiful woman."},
525 { GEN_M, moRoseBeauty, "Handsome Gardener",
526 "Tall, strong, and holding a flower in his hand. You could "
527 "not bring yourself to attack such a handsome man."},
528 { GEN_F, moRusalka, "Rusałka",
529 "A malicious water being. When you kill her, she changes the tile you are standing on, from land to shallow water, or from shallow water to deep water."},
530 { GEN_M, moRusalka, "Topielec",
531 "A malicious water being. When you kill him, he changes the tile you are standing on, from land to shallow water, or from shallow water to deep water."},
532 };
533
534 // --- items ---
535
536 #if HDR
537 enum eOrbshape { osNone, osLove, osRanged, osOffensive, osFriend, osUtility, osDirectional, osWarping, osFrog, osPowerUtility, osProtective, osMovement, osTerraform };
538
539 static const flagtype ZERO = 0;
540
541 static const flagtype IF_SHARD = Flag(0);
542 static const flagtype IF_FIREPROOF = Flag(1);
543 static const flagtype IF_PROTECTION = Flag(2);
544 static const flagtype IF_EMPATHY = Flag(3);
545 static const flagtype IF_RANGED = Flag(4);
546 static const flagtype IF_SHMUPLIFE = Flag(5);
547 static const flagtype IF_REVIVAL = Flag(6);
548 static const flagtype IF_CURSE = Flag(7);
549
550 // 0 = basic treasure, 1 = other item, 2 = power orb, 3 = not an item
551 #define IC_TREASURE 0
552 #define IC_OTHER 1
553 #define IC_ORB 2
554 #define IC_NAI 3
555
556 struct itemtype {
557 char glyph;
558 color_t color;
559 const char *name;
560 int itemclass;
561 flagtype flags;
562 eOrbshape orbshape;
563 const char *help;
564 };
565
566 enum eItem {
567 #define ITEM(a,b,c,d,e,f,g,h,i) d,
568 #include "content.cpp"
569 ittypes
570 };
571 #endif
572
573 EX itemtype iinf[ittypes] = {
574 #define ITEM(a,b,c,d,e,f,g,h,i) {a,b,c,e,f,h,i},
575 #include "content.cpp"
576 };
577
578 // --- wall types ---
579
580 #if HDR
581 static const flagtype WF_WATER = Flag(0);
582 static const flagtype WF_BOAT = Flag(1);
583 static const flagtype WF_CHASM = Flag(2);
584 static const flagtype WF_NOFLIGHT = Flag(3);
585 static const flagtype WF_FIRE = Flag(4);
586 static const flagtype WF_THUMPER = Flag(5);
587 static const flagtype WF_ACTIVABLE = Flag(6);
588 static const flagtype WF_ALCHEMY = Flag(7);
589 static const flagtype WF_RED = Flag(8);
590 static const flagtype WF_WALL = Flag(9);
591 static const flagtype WF_PUSHABLE = Flag(10);
592 static const flagtype WF_CONE = Flag(11);
593 static const flagtype WF_STDTREE = Flag(12);
594 static const flagtype WF_GRAVE = Flag(13);
595 static const flagtype WF_REPTILE = Flag(14);
596 static const flagtype WF_HEATCOLOR = Flag(15);
597 static const flagtype WF_HIGHWALL = Flag(16);
598 static const flagtype WF_THORNY = Flag(17);
599 static const flagtype WF_TIMEOUT = Flag(18);
600 static const flagtype WF_CISLAND = Flag(19);
601 static const flagtype WF_SULPHURIC = Flag(20);
602 static const flagtype WF_HALFVINE = Flag(21);
603
604 struct walltype {
605 char glyph;
606 color_t color;
607 const char *name;
608 flagtype flags;
609 int snakelevel;
610 eSlimegroup sg;
611 const char *help;
612 };
613
614 enum eWall {
615 #define WALL(a,b,c,d,e,f,g,h,i) d,
616 #include "content.cpp"
617 walltypes
618 };
619 #endif
620
621 EX walltype winf[walltypes] = {
622 #define WALL(a,b,c,d,e,f,g,h,i) {a,b,c,e,g,h,i},
623 #include "content.cpp"
624 };
625
626 // -- land types ---
627
628 #if HDR
629 static const flagtype LF_GENERATE_ALL = Flag(0);
630 static const flagtype LF_ICY = Flag(1);
631 static const flagtype LF_GRAVITY = Flag(2);
632 static const flagtype LF_EQUI = Flag(3);
633 static const flagtype LF_WARPED = Flag(4);
634 static const flagtype LF_CYCLIC = Flag(5);
635 static const flagtype LF_TECHNICAL = Flag(6);
636 static const flagtype LF_MIRROR = Flag(7);
637 static const flagtype LF_SEA = Flag(8);
638 static const flagtype LF_COASTAL = Flag(9);
639 static const flagtype LF_PURESEA = Flag(10);
640 static const flagtype LF_ELEMENTAL = Flag(11);
641 static const flagtype LF_HAUNTED = Flag(12);
642 static const flagtype LF_TROLL = Flag(13);
643 static const flagtype LF_INMIRROR = Flag(14);
644 static const flagtype LF_INMIRRORORWALL = Flag(15);
645 static const flagtype LF_ELECTRIC = Flag(17);
646
647 struct landtype {
648 color_t color;
649 const char *name;
650 flagtype flags;
651 eItem treasure;
652 const char *help;
653 };
654
655 enum eLand {
656 #define LAND(a,b,c,d,e,f,g) c,
657 #include "content.cpp"
658 landtypes
659 };
660
661 extern color_t floorcolors[landtypes];
662 #endif
663
664 EX const landtype linf[landtypes] = {
665 #define LAND(a,b,c,d,e,f,g) {a,b,d,e,g},
666 #include "content.cpp"
667 };
668
669 #if HDR
670 struct landtacinfo { eLand l; int tries, multiplier; };
671 #endif
672
673 EX vector<landtacinfo> land_tac = {
674 {laIce, 10, 1}, {laDesert, 10, 1},
675 {laHunting, 5, 2},
676 {laMotion, 10, 1}, {laCaves, 10, 1}, {laAlchemist, 10, 1},
677 {laJungle, 10, 1}, {laMirror, 10, 1}, {laZebra, 10, 1}, {laPalace, 10, 1},
678 {laOcean, 10, 1}, {laLivefjord, 10, 1}, {laWarpCoast, 10, 1}, {laRlyeh, 10, 1}, {laHell, 10, 1},
679 {laDryForest, 10, 1}, {laWineyard, 10, 1}, {laSwitch, 10, 1}, {laReptile, 10, 1},
680 {laDeadCaves, 10, 1}, {laGraveyard, 10, 1},
681 {laHaunted, 10, 1},
682 {laIvoryTower, 10, 1}, {laEndorian, 10, 1}, {laMountain, 5, 2}, {laDungeon, 5, 2},
683 {laRuins, 10, 1}, {laEmerald, 10, 1},
684 {laCocytus, 10, 1},
685
686 {laCaribbean, 5, 2}, {laWhirlpool, 5, 2}, {laKraken, 5, 2},
687 {laTemple, 5, 2}, {laMinefield, 5, 2},
688 {laPower, 5, 2}, {laHive, 5, 2}, {laRedRock, 5, 2}, {laStorms, 5, 2}, {laOvergrown, 5, 2},
689 {laClearing, 5, 2},
690 {laWhirlwind, 5, 2},
691 {laBlizzard, 10, 1},
692 {laRose, 5, 2}, {laVolcano, 10, 1}, {laDragon, 2, 5}, {laTortoise, 1, 10},
693 {laBurial, 5, 2},
694 {laElementalWall, 10, 1}, {laTrollheim, 5, 2},
695 {laPrairie, 5, 2}, {laBull, 5, 2}, {laTerracotta, 10, 1},
696 {laDice, 5, 2}, {laCursed, 5, 2},
697
698 {laCrossroads, 10, 1}, {laCrossroads2, 10, 1}, {laCrossroads3, 10, 1}, {laCrossroads4, 10, 1}, {laCrossroads5, 5, 2},
699
700 {laCamelot, 1, 100},
701 {laWildWest, 10, 1},
702 {laDual, 10, 1},
703 {laSnakeNest, 10, 1},
704 {laDocks, 10, 1},
705
706 {laBrownian, 10, 1},
707 {laVariant, 10, 1},
708 {laWestWall, 10, 1},
709 {laWet, 10, 1}, {laFrog, 10, 1}, {laEclectic, 10, 1},
710 };
711
712 EX vector<eLand> randlands = {
713 laIce, laDesert, laCaves, laAlchemist, laGraveyard, laPower, laLivefjord, laZebra,
714 laRlyeh, laDryForest, laEmerald, laWineyard, laDeadCaves, laRedRock,
715 laOvergrown, laWildWest, laWarpCoast, laRuins, laBull, laDragon, laReptile, laDocks,
716 laFrog, laWet, laZebra
717 };
718
719 #if HDR
720 enum eGeometry {
721 gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
722 gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,
723 gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron,
724 gBinary3, gCubeTiling, gCell120, gECell120, gRhombic3, gBitrunc3,
725 gSpace534, gSpace435,
726 gCell5,
727 gCell16, gECell16,
728 gCell8, gECell8,
729 gCell24, gECell24,
730 gCell600, gECell600,
731 gHoroTris, gHoroRec, gHoroHex,
732 gField435, gField534,
733 gBinary4, gSol,
734 gKiteDart2, gKiteDart3, gNil, gProduct, gRotSpace,
735 gTernary, gNIH, gSolN, gInfOrder, gSpace336, gSpace344, gCrystal344,
736 gArnoldCat, gArbitrary, gInfOrder4, gCrystal534,
737 gSpace535, gSpace536, gSeifertCover, gSeifertWeber, gHomologySphere,
738 gInfOrderMixed, gSpace436, gFake,
739 gSpace345, gSpace353, gSpace354, gSpace355,
740 gGUARD};
741
742 enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSolNIH, gcNil, gcProduct, gcSL2 };
743
744 enum class eVariation { bitruncated, pure, goldberg, irregular, dual, untruncated, warped, unrectified, subcubes, coxeter, dual_subcubes, bch, bch_oct };
745
746 typedef int modecode_t;
747
748 /** only the actual geometry */
749 struct geometryinfo1 {
750 /** geometry class */
751 eGeometryClass kind;
752 /** dimension of the gameplay (2 for crystal) */
753 int gameplay_dimension;
754 /** dimension of the graphics, may be greater than gameplay_dimension with vid.always3 on */
755 int graphical_dimension;
756 /** dimension of the homogeneous vector space used, usually graphical_dimension+1, but 3 in product */
757 int homogeneous_dimension;
758 /** signature of the scalar product used */
759 int sig[4];
760 };
761
762 struct geometryinfo {
763 std::string tiling_name;
764 std::string quotient_name;
765 const char* menu_displayed_name;
766 const char* shortname;
767 int sides;
768 int vertex;
769 flagtype flags;
770 geometryinfo1 g;
771 std::array<int,2> distlimit; // bitrunc, non-bitrunc
772 eVariation default_variation;
773 };
774
775 static const flagtype qBOUNDED = 1;
776 static const flagtype qANYQ = 2;
777 static const flagtype qNONORIENTABLE = 4;
778 static const flagtype qSMALL = 8;
779
780 static const flagtype qFIELD = 16;
781 static const flagtype qDOCKS = 32;
782 static const flagtype qZEBRA = 64;
783
784 static const flagtype qELLIPTIC = 128;
785
786 static const flagtype qBINARY = 256;
787 static const flagtype qKITE = 512;
788
789 static const flagtype qREGULAR = 1024; /* not set! */
790 static const flagtype qARCHI = 2048;
791 static const flagtype qHYBRID = 4096;
792 static const flagtype qCRYSTAL = 8192;
793 static const flagtype qSOL = 16384;
794 static const flagtype qEXPERIMENTAL = 32768;
795 static const flagtype qNIH = 65536;
796
797 static const flagtype qIDEAL = 131072;
798 static const flagtype qHUGE_BOUNDED = 262144;
799 static const flagtype qOPTQ = Flag(19);
800 static const flagtype qSINGLE = Flag(20);
801
802 static const flagtype qDEPRECATED = Flag(21);
803 static const flagtype qINFMIXED = Flag(22);
804
805 static const flagtype qRAYONLY = Flag(23);
806 static const flagtype qAFFINE = Flag(24);
807
808 static const flagtype qULTRA = Flag(25);
809
810 static const flagtype qPORTALSPACE = Flag(26);
811
812 static const flagtype qSTRETCHABLE = Flag(27);
813
814 static const flagtype qCAT = Flag(28);
815
816 // note: dnext assumes that x&7 equals 7
817 static const int SEE_ALL = 50;
818 static const int OINF = 100;
819
820 extern eGeometry geometry;
821 extern eVariation variation;
822 #endif
823
824 static const flagtype qsNONOR = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE;
825 static const flagtype qsNONORE = qsNONOR | qELLIPTIC;
826 static const flagtype qsBQ = qANYQ | qSMALL | qBOUNDED;
827 static const flagtype qsSMALL = qANYQ | qSMALL | qBOUNDED;
828 static const flagtype qsSMALLN = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE;
829 static const flagtype qsZEBRA = qANYQ | qSMALL | qBOUNDED | qZEBRA;
830 static const flagtype qsFIELD = qANYQ | qFIELD | qBOUNDED;
831 static const flagtype qsDOCKS = qANYQ | qSMALL | qBOUNDED | qDOCKS;
832 static const flagtype qsSMALLB = qSMALL | qBOUNDED;
833 static const flagtype qsSMALLBF = qsSMALLB | qsFIELD | qANYQ;
834 static const flagtype qsSMALLBE = qsSMALLB | qELLIPTIC | qANYQ;
835 static const flagtype qsBP = qBINARY | qKITE;
836
837 static const flagtype qsSINGLE = qANYQ | qSMALL | qBOUNDED | qSINGLE;
838
839 EX geometryinfo1 giEuclid2 = { gcEuclid, 2, 2, 3, {1,1, 0,0 } };
840 EX geometryinfo1 giHyperb2 = { gcHyperbolic, 2, 2, 3, {1,1,-1,0 } };
841 EX geometryinfo1 giSphere2 = { gcSphere, 2, 2, 3, {1,1,+1,0 } };
842
843 EX geometryinfo1 giEuclid3 = { gcEuclid, 3, 3, 4, {1,1, 1,0 } };
844 EX geometryinfo1 giHyperb3 = { gcHyperbolic, 3, 3, 4, {1,1, 1,-1} };
845 EX geometryinfo1 giSphere3 = { gcSphere, 3, 3, 4, {1,1, 1,+1} };
846
847 EX geometryinfo1 giSolNIH = { gcSolNIH, 3, 3, 4, {1,1, 1,0 } };
848 EX geometryinfo1 giNil = { gcNil, 3, 3, 4, {1,1, 1,0 } };
849 EX geometryinfo1 giProduct = { gcSL2, 3, 3, 4, {1,1, 1,0 } /* will be filled in product::configure() */ };
850 EX geometryinfo1 giSL2 = { gcSL2, 3, 3, 4, {1,1,-1,-1} };
851
852 EX modecode_t no_code = 0x1;
853
854 /** list of available geometries */
855 EX vector<geometryinfo> ginf = {
856 {"{7,3}", "none", "{7,3} (standard HyperRogue map)", "HR", 7, 3, 0, giHyperb2, {{7, 5}}, eVariation::bitruncated},
857 {"{6,3}", "none", "{6,3} (euclidean Hex grid)", "euclid", 6, 3, qOPTQ, giEuclid2, {{7, 7}}, eVariation::bitruncated},
858 {"{5,3}", "none", "{5,3} (dodecahedron)", "sphere", 5, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
859 {"{5,3}", "elliptic", "elliptic geometry in {5,3}", "elliptic", 5, 3, qsNONORE, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
860 {"{7,3}", "Zebra", "Zebra quotient", "Zebra", 7, 3, qsZEBRA, giHyperb2, {{7, 5}}, eVariation::bitruncated},
861 {"{7,3}", "field", "field quotient", "field", 7, 3, qsFIELD, giHyperb2, {{7, 5}}, eVariation::bitruncated},
862 {"{6,3}", "torus", "torus/Klein bottle/...", "torus", 6, 3, qsBQ|qDEPRECATED, giEuclid2, {{7, 7}}, eVariation::bitruncated},
863 {"{8,3}", "none", "{8,3} (like standard but with octagons)", "oct", 8, 3, 0, giHyperb2, {{6, 4}}, eVariation::bitruncated},
864 {"{5,4}", "none", "{5,4} (four pentagons)", "4x5", 5, 4, 0, giHyperb2, {{6, 4}}, eVariation::bitruncated},
865 {"{6,4}", "none", "{6,4} (four hexagons)", "4x6", 6, 4, 0, giHyperb2, {{5, 3}}, eVariation::bitruncated},
866 {"{7,4}", "none", "{7,4} (four heptagons)", "4x7", 7, 4, 0, giHyperb2, {{4, 3}}, eVariation::bitruncated},
867 {"{4,3}", "none", "{4,3} (cube)", "3x4", 4, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
868 {"{3,3}", "none", "{3,3} (tetrahedron)", "3x3", 3, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
869 {"{4,4}", "none", "{4,4} (Euclidean square grid)", "4x4", 4, 4, qOPTQ, giEuclid2, {{7, 7}}, eVariation::bitruncated},
870 {"{4,3}", "elliptic", "elliptic geometry in {4,3}", "e3x4", 4, 3, qsNONORE, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
871 {"{7,3}", "Klein", "Klein Quartic", "Klein", 7, 3, qsSMALL, giHyperb2, {{7, 5}}, eVariation::bitruncated},
872 {"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, giHyperb2, {{6, 4}}, eVariation::bitruncated},
873 {"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, giHyperb2, {{6, 4}}, eVariation::bitruncated},
874 {"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, giHyperb2, {{7, 5}}, eVariation::bitruncated},
875 {"binary","none", "variant of the binary tiling", "binary", 7, 3, qBINARY, giHyperb2, {{7, 5}}, eVariation::pure},
876 {"Arch", "none", "Archimedean", "A", 7, 3, qARCHI, giHyperb2, {{7, 5}}, eVariation::pure},
877 {"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, giHyperb2, {{7, 5}}, eVariation::bitruncated},
878 {"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, giHyperb2, {{6, 4}}, eVariation::bitruncated},
879 {"{12,3}","M3", "Schmutz's M(3)", "M3", 12, 3, qsSMALL, giHyperb2, {{4, 2}}, eVariation::bitruncated},
880 {"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, giHyperb2, {{4, 2}}, eVariation::bitruncated},
881 {"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ|qCRYSTAL, giHyperb2, {{5, 3}}, eVariation::pure},
882 {"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
883 {"bin{4,4}", "none", "{4,4} on horospheres", "bin44", 9, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
884 {"{4,3,4}","none", "{4,3,4} cube tiling", "434", 6, 4, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
885 {"{5,3,3}","none", "{5,3,3} 120-cell", "533", 12, 3, qsSMALLB | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
886 {"{5,3,3}", "elliptic","{5,3,3} 120-cell (elliptic space)", "e533", 12, 3, qsSMALLBE | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
887 {"rh{4,3,4}","none", "rhombic dodecahedral honeycomb", "rh434", 12, 3, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
888 {"2t{4,3,4}","none", "bitruncated cubic honeycomb", "2t434", 14, 3, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
889 {"{5,3,4}","none", "{5,3,4} hyperbolic honeycomb", "534", 12, 4, 0, giHyperb3, {{7, 2}}, eVariation::pure},
890 {"{4,3,5}","none", "{4,3,5} hyperbolic honeycomb", "435", 6, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
891 {"{3,3,3}","none", "{3,3,3} 5-cell", "333", 4, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
892 {"{3,3,4}","none", "{3,3,4} 16-cell", "334", 4, 4, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
893 {"{3,3,4}","elliptic","{3,3,4} 16-cell (elliptic space)", "e334", 4, 4, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
894 {"{4,3,3}","none", "{4,3,3} 8-cell", "433", 6, 4, qsSMALLB | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
895 {"{4,3,3}","elliptic","{4,3,3} 8-cell (elliptic space)", "e433", 6, 4, qsSMALLBE | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
896 {"{3,4,3}","none", "{3,4,3} 24-cell", "343", 8, 3, qsSMALLB | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
897 {"{3,4,3}","elliptic","{3,4,3} 24-cell (elliptic space)", "e343", 8, 3, qsSMALLBE | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
898 {"{3,3,5}","none", "{3,3,5} 600-cell", "335", 4, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
899 {"{3,3,5}","elliptic","{3,3,5} 600-cell (elliptic space)", "e335", 4, 3, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
900 {"bin{3,6}", "none", "{3,6} on horospheres", "bin36", 8, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
901 {"bin-rect", "none", "rectangles on horospheres", "bin44/2", 7, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
902 {"bin{6,3}", "none", "{6,3} on horospheres", "bin63", 14, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
903 {"{4,3,5}","field", "{4,3,5} field quotient space", "f435", 6, 5, qsSMALLBF | qDEPRECATED, giHyperb3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
904 {"{5,3,4}","field", "{5,3,4} field quotient space", "f435", 12, 4, qsSMALLBF | qDEPRECATED, giHyperb3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
905 {"binary4","none", "standard binary tiling", "binary4", 5, 3, qBINARY, giHyperb2, {{7, 5}}, eVariation::pure},
906 {"sol", "none", "Solv geometry", "sol", 8, 3, qBINARY|qSOL, giSolNIH, {{7, 5}}, eVariation::pure},
907 {"kd2", "none", "kite-and-dart", "kd2", 4, 3, qKITE, giEuclid2, {{7, 7}}, eVariation::pure},
908 {"kd3", "none", "kite-and-dart on horospheres", "kd3", 12, 3, qsBP, giHyperb3, {{7, 3}}, eVariation::pure},
909 {"nil", "none", "Nil geometry", "nil", 6, 3, qOPTQ, giNil, {{7, 5}}, eVariation::pure},
910 {"product","none", "product space", "product", 7, 3, qHYBRID, giProduct, {{7, 3}}, eVariation::pure},
911 {"twisted","none", "rotation space", "twisted", 7, 3, qHYBRID, giSL2, {{6, 4}}, eVariation::pure},
912 {"ternary","none", "standard ternary tiling", "ternary", 6, 3, qBINARY, giHyperb2, {{6, 4}}, eVariation::pure},
913 {"3x2", "none", "stretched hyperbolic", "3:2", 11, 3, qBINARY|qNIH, giSolNIH, {{6, 3}}, eVariation::pure},
914 {"3x1/2", "none", "stretched Solv", "3:1/2", 9, 3, (qBINARY|qSOL|qNIH), giSolNIH, {{7, 3}}, eVariation::pure},
915 {"{3,oo}", "none", "{3,∞} (infinite triangles)", "oox3", 3, OINF, qIDEAL, giHyperb2, {{7, 7}}, eVariation::pure},
916 {"{3,3,6}","none", "{3,3,6} hyperbolic honeycomb", "336", 4, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
917 {"{3,4,4}","none", "{3,4,4} hyperbolic honeycomb", "344", 8, 4, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
918 {"{3,4,4}","Crystal", "4D crystal in H3", "Cryst3" , 8, 4, qIDEAL | qANYQ | qCRYSTAL, giHyperb3, {{7, 3}}, eVariation::pure},
919 {"cat", "cat", "Arnold's cat mapping torus", "cat", 12, 3, qBINARY | qSOL | qsBQ | qOPTQ | qCAT, giSolNIH, {{6, 4}}, eVariation::pure},
920 {"file", "none", "load from file", "file", 7, 3, 0, giEuclid2, {{7, 5}}, eVariation::pure},
921 {"{4,oo}", "none", "{4,∞} (infinite squares)", "oox4", 4, OINF, qIDEAL, giHyperb2, {{5, 5}}, eVariation::pure},
922 {"{5,3,4}","Crystal", "6D crystal in H3", "Cryst6" , 12, 4, qANYQ | qCRYSTAL, giHyperb3, {{7, 3}}, eVariation::pure},
923 {"{5,3,5}","none", "{5,3,5} hyperbolic honeycomb", "535", 12, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
924 {"{5,3,6}","none", "{5,3,6} hyperbolic honeycomb", "536", 12, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
925 {"{5,3,5}","SWh", "{5,3,5} quotient", "535c", 12, 5, qsSMALLB | qANYQ, giHyperb3, {{7, 2}}, eVariation::pure},
926 {"{5,3,5}","SW", "Seifert-Weber space", "535s", 12, 5, qsSINGLE, giHyperb3, {{7, 2}}, eVariation::pure},
927 {"{5,3,3}","SW", "Poincaré homology sphere", "533s", 12, 3, qsSINGLE, giSphere3, {{7, 2}}, eVariation::pure},
928 {"{?,oo}", "none", "{3/4,∞} (infinite triangles and squares)", "ooxm", 3, OINF, qIDEAL | qINFMIXED, giHyperb2, {{6, 6}}, eVariation::pure},
929 {"{4,3,6}","none", "{4,3,6} hyperbolic honeycomb", "436", 6, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
930 {"?", "none", "fake", "", 0, 0, qRAYONLY, giHyperb3, {{7, 2}}, eVariation::pure},
931 {"{3,4,5}","none", "{3,4,5} hyperbolic honeycomb", "345", 8, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
932 {"{3,5,3}","none", "{3,5,3} hyperbolic honeycomb", "353", 20, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
933 {"{3,5,4}","none", "{3,5,4} hyperbolic honeycomb", "354", 20, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
934 {"{3,5,5}","none", "{3,5,5} hyperbolic honeycomb", "355", 20, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
935 };
936 // bits: 9, 10, 15, 16, (reserved for later) 17, 18
937
938 #if HDR
939 namespace mf {
940 static const flagtype azimuthal = 1;
941 static const flagtype cylindrical = 2;
942 static const flagtype equiarea = 4;
943 static const flagtype equidistant = 8;
944 static const flagtype conformal = 16;
945 static const flagtype euc_boring = 32;
946 static const flagtype space = 64;
947 static const flagtype hyper_only = 128;
948 static const flagtype hyper_or_torus = 256;
949 static const flagtype pseudocylindrical = 512; /* includes cylindrical */
950 static const flagtype equivolume = 1024;
951 static const flagtype twopoint = 2048;
952 static const flagtype uses_bandshift = 4096;
953 static const flagtype broken = 8192; /* in spherical case, these are broken along the meridian 180 deg */
954
955 static const flagtype band = (cylindrical | pseudocylindrical | uses_bandshift);
956 static const flagtype pseudoband = (pseudocylindrical | uses_bandshift);
957 }
958
959 struct modelinfo {
960 const char *name_hyperbolic;
961 const char *name_euclidean;
962 const char *name_spherical;
963
964 flagtype flags;
965
966 int is_azimuthal;
967 int is_band;
968 int is_equiarea;
969 int is_equidistant;
970 int is_conformal;
971 const char* name;
972 };
973
974 enum eModel : int {
975 mdDisk, mdHalfplane, mdBand, mdPolygonal, mdFormula,
976 // 5..8.
977 mdEquidistant, mdEquiarea, mdBall, mdHyperboloid,
978 // 9..13
979 mdHemisphere, mdBandEquidistant, mdBandEquiarea, mdSinusoidal, mdTwoPoint,
980 // 14..16
981 mdFisheye, mdJoukowsky, mdJoukowskyInverted,
982 // 17..19
983 mdRotatedHyperboles, mdSpiral, mdPerspective,
984 // 20..24
985 mdEquivolume, mdCentralInversion, mdSimulatedPerspective, mdTwoHybrid, mdGeodesic,
986 // 25..27
987 mdMollweide, mdCentralCyl, mdCollignon,
988 // 28..31
989 mdHorocyclic, mdQuadrant, mdAxial, mdAntiAxial,
990 // 32..38
991 mdWerner, mdAitoff, mdHammer, mdLoximuthal, mdMiller, mdGallStereographic, mdWinkelTripel,
992 // 39..
993 mdPoorMan, mdPanini, mdRetroCraig, mdRetroLittrow, mdRetroHammer, mdThreePoint,
994 // 45..
995 mdGUARD, mdPixel, mdHyperboloidFlat, mdPolynomial, mdManual
996 };
997 #endif
998
999 // remember to match the following mask when specifying codes for extra geometries: 0x78600
1000 // (other bits are used for other information)
1001
1002 #define X3(x) x, x, x
1003 #define DEFAULTS 0, 0, 0, 0, 0, nullptr
1004
1005 /** list of available models (i.e., projections) */
1006 EX vector<modelinfo> mdinf = {
1007 {"disk/Gans", "general perspective", "general perspective", mf::azimuthal | mf::conformal, DEFAULTS},
1008 {"half-plane", "inversion", "stereographic projection [VR]", mf::conformal, DEFAULTS},
1009 {"band", "band", "Mercator", mf::band | mf::conformal, DEFAULTS},
1010 {X3("polygonal"), mf::conformal, DEFAULTS},
1011 {X3("formula"), 0, DEFAULTS},
1012 {X3("azimuthal equidistant"), mf::azimuthal | mf::equidistant | mf::euc_boring, DEFAULTS},
1013 {X3("azimuthal equi-area"), mf::azimuthal | mf::equiarea | mf::euc_boring, DEFAULTS},
1014 {X3("ball model"), mf::conformal | mf::azimuthal | mf::space, DEFAULTS},
1015 {"Minkowski hyperboloid", "plane", "sphere", mf::conformal | mf::space | mf::euc_boring, DEFAULTS},
1016 {"hemisphere", "sphere", "sphere", mf::conformal | mf::space, DEFAULTS},
1017 {X3("band equidistant"), mf::band | mf::equidistant | mf::euc_boring, DEFAULTS},
1018 {X3("band equi-area"), mf::band | mf::equiarea | mf::euc_boring, DEFAULTS},
1019 {X3("sinusoidal"), mf::pseudoband | mf::equiarea | mf::euc_boring, DEFAULTS},
1020 {X3("two-point equidistant"), mf::equidistant | mf::euc_boring | mf::twopoint, DEFAULTS},
1021 {X3("fisheye"), 0, DEFAULTS},
1022 {X3("Joukowsky transform"), mf::hyper_only | mf::conformal, DEFAULTS},
1023 {X3("Joukowsky+inversion"), mf::hyper_only | mf::conformal, DEFAULTS},
1024 {X3("rotated hyperboles"), mf::hyper_only, DEFAULTS},
1025 {X3("spiral/ring"), mf::hyper_or_torus | mf::uses_bandshift, DEFAULTS},
1026 {X3("native perspective"), 0, DEFAULTS},
1027 {X3("azimuthal equi-volume"), mf::azimuthal | mf::equivolume | mf::euc_boring, DEFAULTS},
1028 {X3("central inversion"), mf::azimuthal | mf::conformal, DEFAULTS},
1029 {X3("two-point azimuthal"), mf::euc_boring | mf::twopoint, DEFAULTS},
1030 {X3("two-point hybrid"), mf::euc_boring | mf::twopoint, DEFAULTS},
1031 {X3("geodesic"), 0, DEFAULTS},
1032 {X3("Mollweide"), mf::euc_boring | mf::pseudoband | mf::equiarea, DEFAULTS},
1033 {X3("central cylindrical"), mf::euc_boring | mf::band, DEFAULTS},
1034 {X3("Collignon"), mf::pseudoband | mf::equiarea, DEFAULTS},
1035 {X3("horocyclic coordinates"), mf::euc_boring, DEFAULTS},
1036 {X3("quadrant coordinates"), mf::euc_boring, DEFAULTS},
1037 {X3("axial coordinates"), mf::euc_boring, DEFAULTS},
1038 {X3("anti-axial coordinates"), mf::euc_boring, DEFAULTS},
1039 {X3("Werner projection"), mf::euc_boring | mf::broken, DEFAULTS}, // keep distances from pole, and distances along parallels
1040 {X3("Aitoff projection"), mf::euc_boring | mf::broken, DEFAULTS}, // halve longitudes, do azequid, double x
1041 {X3("Hammer projection"), mf::euc_boring | mf::broken, DEFAULTS}, // halve longitudes, do azequia, double x
1042 {X3("loximuthal projection"), mf::euc_boring | mf::broken, DEFAULTS}, // map loxodromes azimuthally and equidistantly
1043 {X3("Miller projection"), mf::euc_boring | mf::band, DEFAULTS}, // scale latitude 4/5 -> Mercator -> 5/4
1044 {X3("Gall stereographic"), mf::euc_boring | mf::band, DEFAULTS}, // like central cylindrical but stereographic
1045 {X3("Winkel tripel"), mf::euc_boring | mf::broken, DEFAULTS}, // mean of equirec and Aitoff
1046 {X3("Poor man's square"), mf::euc_boring, DEFAULTS}, //
1047 {X3("Panini projection"), mf::euc_boring, DEFAULTS}, //
1048 {X3("Craig retroazimuthal"), mf::euc_boring | mf::broken, DEFAULTS}, // retroazimuthal cylindrical
1049 {X3("Littrow retroazimuthal"), mf::euc_boring | mf::broken, DEFAULTS}, // retroazimuthal conformal
1050 {X3("Hammer retroazimuthal"), mf::euc_boring, DEFAULTS}, // retroazimuthal equidistant
1051 {X3("three-point equidistant"), mf::euc_boring, DEFAULTS},
1052 {X3("guard"), 0, DEFAULTS},
1053 {X3("polynomial"), mf::conformal, DEFAULTS},
1054 };
1055
1056 #undef X3
1057 #undef DEFAULTS
1058
1059 #if HDR
orbProtection(eItem it)1060 static inline bool orbProtection(eItem it) { return false; } // not implemented
1061
1062 // these markers use lands which never appear on barrier sides
1063
1064 const eLand NOWALLSEP = laNone;
1065 const eLand NOWALLSEP_SWAP = laMountain;
1066 const eLand NOWALLSEP_WALL = laHauntedWall;
1067 const eLand NOWALLSEP_USED = laWhirlpool;
1068 const eLand NOWALLSEP_WALL_CPOS = laBarrier;
1069 const eLand NOWALLSEP_WALL_CNEG = laOceanWall;
1070 const eLand NOWALLSEP_WALL_EPOS = laClearing;
1071 const eLand NOWALLSEP_WALL_ENEG = laPrincessQuest;
1072
1073 #endif
1074
1075 }
1076