mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-30 15:39:54 +00:00
1124 lines
57 KiB
C++
1124 lines
57 KiB
C++
// Hyperbolic Rogue -- items, monsters, walls, lands, descriptions, etc.
|
|
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
|
|
|
|
/** \file classes.cpp
|
|
* \brief items, monsters, walls, lands, descriptions, etc.
|
|
*
|
|
* See content.cpp for actual items, monsters, walls and lands.
|
|
*/
|
|
|
|
#include "hyper.h"
|
|
namespace hr {
|
|
|
|
// --- help ---
|
|
|
|
const char *wormdes =
|
|
"These huge monsters normally live below the sand, but your movements have "
|
|
"disturbed them. They are too big to be slain with your "
|
|
"weapons, but you can defeat them by making them unable to move. "
|
|
"This also produces some Spice. They move two times slower than you.";
|
|
|
|
const char *cocytushelp =
|
|
"This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.";
|
|
|
|
const char *tentdes =
|
|
"The tentacles of Cthulhu are like sandworms, but longer. "
|
|
"They also withdraw one cell at a time, instead of exploding instantly.";
|
|
|
|
const char *gameboardhelp =
|
|
"Ever wondered how some boardgame would look on the hyperbolic plane? "
|
|
"I wondered about Go, so I have created this feature. Now you can try yourself!\n"
|
|
"Enter = pick up an item (and score), space = clear an item\n"
|
|
"Other keys place orbs and terrain features of various kinds\n"
|
|
"In the periodic editor, press 0-4 to switch walls in different ways\n"
|
|
;
|
|
|
|
const char *ivydes =
|
|
"A huge plant growing in the Jungle. Each Ivy has many branches, "
|
|
"and one branch grows per each of your moves. Branches grow in a clockwise "
|
|
"order. The root itself is vulnerable.";
|
|
|
|
const char *slimehelp =
|
|
"The Alchemists produce magical potions from pools of blue and red slime. You "
|
|
"can go through these pools, but you cannot move from a blue pool to a red "
|
|
"pool, or vice versa. Pools containing items count as colorless, and "
|
|
"they change color to the PC's previous color when the item is picked up. "
|
|
"Slime beasts also have to keep to their own color, "
|
|
"but when they are killed, they explode, destroying items and changing "
|
|
"the color of the slime and slime beasts around them.";
|
|
|
|
const char *gdemonhelp =
|
|
"These creatures are slow, but very powerful... more powerful than you. "
|
|
"You need some more experience in demon fighting before you will be able to defeat them. "
|
|
"Even then, you will be able to slay this one, but more powerful demons will come...\n\n"
|
|
"Each 10 lesser demons you kill, you become powerful enough to kill all the greater "
|
|
"demons on the screen, effectively turning them into lesser demons.";
|
|
|
|
const char *ldemonhelp =
|
|
"These creatures are slow, but they often appear in large numbers.";
|
|
|
|
const char *trollhelp =
|
|
"A big monster from the Living Caves. A dead Troll will be reunited "
|
|
"with the rocks, causing some walls to grow around its body.";
|
|
|
|
EX const char *trollhelp2 =
|
|
" Additionally, all items around the killed Troll will be destroyed.";
|
|
|
|
const char *trollhelpX =
|
|
"There are several species of trolls living in the hyperbolic world. "
|
|
"Some of them leave this wall behind them when they die.";
|
|
|
|
const char *camelothelp =
|
|
"The Knights of the Round Table are the greatest warriors of these lands. "
|
|
"They are not very inventive with names though, as they call each of their "
|
|
"castles Camelot. "
|
|
"You are probably worthy of joining them, but they will surely give you "
|
|
"some quest to prove yourself...\n\n"
|
|
"Each castle contains a single treasure, the Holy Grail, in the center. "
|
|
"The radius of the Round Table is usually 28, but after you find a Holy Grail "
|
|
"successfully, each new castle (and each Round Table) you find will be bigger.";
|
|
|
|
const char *templehelp =
|
|
"The temple of Cthulhu consists of many concentric circles of columns. "
|
|
"You will surely encounter many Cultists there, who believe that a pilgrimage "
|
|
"to the inner circles will bring them closer to Cthulhu himself, and Grimoires "
|
|
"which surely contain many interesting secrets.\n\n"
|
|
"The circles in the temple of Cthulhu are actually horocycles. They are "
|
|
"infinite, and there is an infinite number of them.";
|
|
|
|
const char *barrierhelp =
|
|
"Huge, impassable walls which separate various lands.";
|
|
|
|
const char *cavehelp =
|
|
"This cave contains walls which are somehow living. After each turn, each cell "
|
|
"counts the number of living wall and living floor cells around it, and if it is "
|
|
"currently of a different type than the majority of cells around it, it switches. "
|
|
"Items count as three floor cells, and dead Trolls count as five wall cells. "
|
|
"Some foreign monsters also count as floor or wall cells.\n";
|
|
|
|
const char *vinehelp =
|
|
"The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n"
|
|
"Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.";
|
|
|
|
const char *hvinehelp =
|
|
"A vine is growing here... but only on a half of the cell. How is that even possible?!"
|
|
"Most monsters cannot move from this cell to the cell containing the other half. "
|
|
"Vine spirits can move only to the adjacent cells which are also adjacent to the "
|
|
"other half.";
|
|
|
|
const char *deadcavehelp =
|
|
"Somehow, this cave has not received the spark of Life yet.";
|
|
|
|
const char *foresthelp =
|
|
"This forest is quite dry. Beware the bushfires!\n"
|
|
"Trees catch fire on the next turn. The temperature of the grass cells "
|
|
"rises once per turn for each fire nearby, and becomes fire itself "
|
|
"when its temperature has risen 10 times.\n"
|
|
"You can also chop down the trees. Big trees take two turns to chop down.";
|
|
|
|
const char *hivehelp =
|
|
"The Hive is filled with Hyperbugs. They are huge insects which look a bit like "
|
|
"ants, a bit like bees, and a bit like roaches. "
|
|
"They live in circular nests, and an army of Hyperbugs will attack any intruder, "
|
|
"including you and enemy Hyperbugs. Will you manage to get to the "
|
|
"heart of such a nest, and get the precious Royal Jelly?";
|
|
|
|
const char *redrockhelp =
|
|
"This land contains high rock formations. Most of the valley is at level 0, "
|
|
"while items are found at level 3. It is impossible to gain two or more levels, "
|
|
"or to lose three levels, in a single move, (attacks are possible at any "
|
|
"difference, though). Kill Red Trolls and Rock Snakes to make a cell higher.";
|
|
|
|
const char *caribbeanhelp =
|
|
"This dangerous sea contains nasty sharks and pirates. ";
|
|
|
|
const char *cislandhelp =
|
|
"The islands of Caribbean are infinite and circular, and "
|
|
"the pirates probably have hidden their treasures somewhere far from the coast.";
|
|
|
|
const char *redsnakedes =
|
|
"Rock snakes are similar to Sandworms, but they move each turn. However, they "
|
|
"only move on the hexagonal cells. They are also somewhat longer than the Sandworms.";
|
|
|
|
const char *minedesc =
|
|
"This minefield has been created by the Bomberbirds to protect their valuable eggs. "
|
|
"Mines explode when they are stepped on, creating fire all around them "
|
|
"(this fire never expires in the Minefield). If you don't step on a mine, you "
|
|
"know the number of mines in cells around you. These numbers are marked with "
|
|
"color codes on the cells you have visited.";
|
|
|
|
const char *palacedesc =
|
|
"So better just to concentrate on collecting treasure. "
|
|
"Beware the traps, and the guards, who are hard to kill!";
|
|
|
|
const char *gatedesc =
|
|
"Green pressure plates open all gates in radius 3 around them. "
|
|
"Similarly, red pressure plates close all gates in this radius.";
|
|
|
|
const char *princessdesc =
|
|
"A mouse squeaks at you. It seems that it wants you to go somewhere. "
|
|
"That's interesting, what could you find here?\n\n"
|
|
"Note: in the part of the Palace that you are exploring during this "
|
|
"quest, the distribution of monsters, pressure plates, and items has been "
|
|
"changed somewhat, to make it a bit more suitable for less "
|
|
"experienced players. The number of monsters does not depend on the "
|
|
"number of Hypersian Rugs you have collected, and there are more "
|
|
"opening plates.\n\n"
|
|
"However, even with the normal distribution, it appears that it should be "
|
|
"always possible to reach your goal. If you want this challenge, "
|
|
"select it from the special game modes menu.";
|
|
|
|
const char *elemdesc =
|
|
"The Elemental Planes are divided into four subzones: Planes of Fire, Water, Air, and Earth. "
|
|
"You need to collect a Shard from each Plane to construct an Elemental Gem. "
|
|
"It is dangerous to collect too many Shards of the same type without constructing a Gem.";
|
|
|
|
const char *wildwestdesc =
|
|
"Take a revolver, kill outlaws, collect bounties.\n\n"
|
|
"Note: since this land is anachronistic, it is not available in normal game. "
|
|
"It is only available in special modes.";
|
|
|
|
const char *elecdesc =
|
|
"Whenever after your move there is a connection between a charged and a "
|
|
"grounded cell, there is a short circuit. All cells on any "
|
|
"path connecting a charged and a grounded cell (without repeated cells, "
|
|
"or two consecutive grounded/charged cells) become damaged.\n\n"
|
|
|
|
"Sandstone walls and most creatures are conductive. Great Walls are "
|
|
"isolators, but lands beyond them count as grounded.\n\n"
|
|
|
|
"Fulgurite, the treasure, is created when you manage to short circuit "
|
|
"a sandstone wall, or a Rich Metal Beast.\n\n"
|
|
|
|
"Trolls leave conductive rocks when killed, and Metal Beasts can only "
|
|
"be killed by electricity -- your attacks only stun them, or push "
|
|
"them away if already stunned.";
|
|
|
|
const char *overdesc =
|
|
"The Overgrown Woods are filled with mutant ivies! These plants "
|
|
"grow very fast. Each leaf, after being grown, can grow itself "
|
|
"on the next turn. However, each part is only able to grow "
|
|
"once in 16 turns. Outside of the Overgrown Woods, the Mutant Ivy "
|
|
"may grow only on hexagonal cells.\n\n"
|
|
"Maybe such fast growing plants could help you solve the problem "
|
|
"of hunger in your world? Kill the Mutant Ivies to collect Mutant Saplings.";
|
|
|
|
const char *cleardesc =
|
|
"A clearing in the Overgrown Woods. Obviously, this gives "
|
|
"the Mutant Ivies an infinite space to grow...\n\n"
|
|
"Mutant Fruits rot if they are not adjacent to a Mutant Ivy.";
|
|
|
|
const char *winddesc =
|
|
"Someone has put air fans in these plains, causing strong winds everywhere. "
|
|
"You think that the purpose is to harness the magical power of Air Elementals, but "
|
|
"you are not sure.\n\n"
|
|
"All cells except fans are grouped into three colors according to a pattern. "
|
|
"Wind blows counterclockwise around each group of cells of a single color. "
|
|
"Cells which are blocked by walls, or at distance at most 2 from an Air Elemental, "
|
|
"do not count for this.\n\n"
|
|
"It is illegal to move in a direction which is closer to incoming wind than to "
|
|
"outgoing wind. However, you can move two cells with the wind in a single turn, "
|
|
"and so can the birds.";
|
|
|
|
const char *warningdesc =
|
|
"Warnings are issued when you try to do something that appears dangerous, "
|
|
"like stepping on a known mine, or getting your boat destroyed by "
|
|
"a Kraken without having Orb of the Fish. In some cases the action "
|
|
"might actually be safe -- so you can ignore the warning and do it anyway, "
|
|
"simply by repeating the action.";
|
|
|
|
const char *hauntdesc =
|
|
"A dark forest filled with ghosts and graves. But there is also treasure hidden "
|
|
"deep within... But don't let greed make you stray from your path, as "
|
|
"you can get lost!\n\n"
|
|
"The Haunted Woods are bounded by a single equidistant curve. It is not a circle or horocycle.\n\n";
|
|
|
|
const char *bulldashdesc =
|
|
"Butterflies don't pursue you -- unless you get next to them, they just spin around the obstacles. "
|
|
"They cannot be killed conventionally, but you get treasure when a Raging Bull crashes into a Butterfly. ";
|
|
|
|
const char *prairiedesc =
|
|
"You can find safety in some places in the Prairie, but if you want treasures, "
|
|
"they can be found only on the other side of a giant herd of bulls.";
|
|
|
|
const char *cadesc =
|
|
"A land for people wanting to experiment with cellular automata in the HyperRogue grid. "
|
|
"Rules can be given on the command line; the default rules are:\n"
|
|
"-c07 00100000 -c06 0010000 -c17 00011000 -c16 0001100 -caprob 0.3\n"
|
|
"(-c0 or -c1 can be given if the same rule is to be used for hexagonal "
|
|
"and heptagonal cells).";
|
|
|
|
const char *huntingdesc =
|
|
"The Happy Hunting Ground is the place where hunting is easy; "
|
|
"the spirits of hunters go here after their death, if their life was deemed worthy. "
|
|
"You did not qualify though, so you will not ever be able to find your way to the places "
|
|
"where the hunter spirits and game are... "
|
|
"and their hunting dogs will hunt you instead!\n\n"
|
|
"You hope to use this to learn some "
|
|
"skills in fighting in open hyperbolic space, though.";
|
|
|
|
const char *terradesc =
|
|
"Spending 3-5 turns next to the Terracotta Warriors will cause them to awaken. "
|
|
"They have 7 HP, and get stunned for longer and longer time with each attack.";
|
|
|
|
const char *terraldesc =
|
|
"The Emperor's mausoleum. The army "
|
|
"of Terracotta Warriors is supposed to protect him in his "
|
|
"afterlife, while the traps are to protect the treasures "
|
|
"in the mausoleum from thieves.";
|
|
|
|
const char *arrowtrapdesc =
|
|
"The arrow traps will automatically launch a deadly arrow when stepped on. They are quite old though, so the arrow will "
|
|
"actually fly at the end of the next turn.";
|
|
|
|
const char *lavadesc =
|
|
"The volcanic activity in this land is extremely unstable. "
|
|
"Lava is too hot to walk on. It cools quickly, but another "
|
|
"flow will come soon...";
|
|
|
|
const char *blizzarddesc =
|
|
"Once in the past there lived a tribe whose prophets warned about the great blizzard that was to come and freeze the world. "
|
|
"They thought it was the wrath of the gods, so they put some altars, so that the gods could hear their pleas. "
|
|
"The mighty golems guarded those altars, making sure nobody steals the jewels, because a robbed god is a angry god. "
|
|
"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). "
|
|
"The tribe has frozen to death, altars got covered with snow and ice. Only ice golems still guard them waiting for the spring.";
|
|
|
|
const char *crystaldesc =
|
|
"Yes, this is definitely a crystal. A very regular crystalline structure.\n\n"
|
|
"This land has been designed as a tool to play with various geometries, and it does not appear during a normal gameplay.";
|
|
|
|
const char *NODESC = "No description yet.";
|
|
const char *NODESCYET = "No description yet.";
|
|
const char *GENDERSWITCH = NODESC;
|
|
|
|
// --- monsters ---
|
|
|
|
EX const char *rosedesc =
|
|
"Each eight turns, each rosebush at distance at most 5 from you will "
|
|
"release a wave of alluring scent. Creatures on the frontwave "
|
|
"will move towards where the scent came from. Even if it causes them "
|
|
"to attack their friends or beautiful creatures, or move into water, fire, chasm, or thorns of the rosebush. "
|
|
"Ivies, Ghosts, Rock Snakes, Rose Ladies and Lords, and monsters restricted to a specific "
|
|
"terrain are immune to scents.";
|
|
|
|
EX const char *warpdesc =
|
|
"This part of the world is warped, restricting the movement somewhat. "
|
|
"\"Diagonal\" movement and attacking between triangular cells is not allowed. "
|
|
"Flash, Storms, and Freedom spells ignore this, and Ghosts can move, attack, and "
|
|
"be attacked diagonally.";
|
|
|
|
const char *warplanddesc =
|
|
"This land is warped. Ironically, the coast is completely straight...";
|
|
|
|
const char *roselanddesc =
|
|
"This land is filled with beautiful, but dangerous, creatures and plants.";
|
|
|
|
const char *dragondesc =
|
|
"Dragons are powerful monsters. They are slow, but evil, "
|
|
"and love to pick on creatures who are even slower than "
|
|
"them. They must be stopped!\n\n"
|
|
|
|
"A Dragon moves each two turns. It may attack with all its segments, "
|
|
"or move its whole body forwards or "
|
|
"backwards, it may also move a frontal part backwards. To kill a Dragon, "
|
|
"you need to hit each of its segments. "
|
|
"The head will regenerate on the "
|
|
"turns the Dragon is not moving, so you will usually have to hit it with "
|
|
"your last attack; otherwise, if the head is healthy, it may breathe "
|
|
"fire (at range 3), losing the hitpoint. Killing the Dragon "
|
|
"while still in the Dragon Chasms gives you treasure.";
|
|
|
|
const char *tortoisedesc =
|
|
"Galápagos is the land of Tortoises. "
|
|
"They are very slow, which allows the Dragons to pick on them by "
|
|
"stealing and eating their young. Bring the Baby Tortoises back, "
|
|
"but, there is a catch: the Tortoises come in many varieties, depending "
|
|
"on the part of Galápagos they live in -- there are 21 binary environmental "
|
|
"factors, and thus "
|
|
"2097152 varieties. You'll have to find a "
|
|
"Tortoise which matches the baby exactly!\n\n"
|
|
"Tortoises move each 3 turns, and attacks only stun them.\n\n"
|
|
"Bringing back a Baby Tortoise counts as 5 $$$. The more factors agree in "
|
|
"the given location of Galápagos, the brighter it is shown on your screen.";
|
|
|
|
const char *krakendesc =
|
|
"There are Krakens in your homeland, too... huge sea monsters which "
|
|
"could easily destroy ships. The geometry of this strange world "
|
|
"prevents quick movement of huge objects, "
|
|
"so there are no large ships, only small boats, and "
|
|
"hyperbolic Krakens are relatively small too. Still, you suppose they might be "
|
|
"the widest creatures which could still move at considerable speed...\n\n"
|
|
|
|
"Kraken heads can move only on hexagons. You need to attack all the tentacles to "
|
|
"kill the Kraken. A tentacle cannot attack if it has been attacked on the "
|
|
"same turn. When a Kraken attacks you while you are in a boat, it "
|
|
"destroys the boat, but does not kill you.";
|
|
|
|
const char *halloweendesc =
|
|
"Halloween is a special land, that is available only in the spherical "
|
|
"or elliptic geometry (press 'o' to switch). You play on the surface of "
|
|
"a jack-o'-lantern, "
|
|
"and have to collect as many Treats as possible. Each Treat you collect "
|
|
"brings new monsters to fight, and new magical powers for you. You "
|
|
"have to fight the monsters while effectively managing your limited "
|
|
"resources.";
|
|
|
|
const char *reptiledesc =
|
|
"These reptiles are quite strange creatures. They "
|
|
"spend most of their lives sleeping as floors "
|
|
"that other creatures can walk on. "
|
|
"Sometimes they wake up to hunt their prey, "
|
|
"but they will happily go back to sleep if they "
|
|
"happen to move into a hole on their way. "
|
|
"Your attacks do not kill the Reptiles, but "
|
|
"you can push and stun them.";
|
|
|
|
const char *naturedesc =
|
|
"This Orb allows you to grow like an Ivy. "
|
|
"The Ivy is always rooted in your current location; "
|
|
"moving among the Ivy cells will move the root. "
|
|
"Moving to a new location will cause the Ivy to grow "
|
|
", if an Ivy could make that movement "
|
|
"(otherwise it breaks). "
|
|
"You can also target one of the cells adjacent to your ivy "
|
|
"(not to you) to grow or attack there.";
|
|
|
|
const char *mirroreddesc =
|
|
"A perfect mirror wall. It is unbreakable "
|
|
"and impassable "
|
|
"even for aethereal beings, and everything "
|
|
"you see inside is just an image of "
|
|
"the real world; you can swing your sword "
|
|
"at them, but that will not destroy them "
|
|
"in the real world. "
|
|
"Mirror walls reflect Mimics, lightning bolts, and "
|
|
"missiles perfectly.";
|
|
|
|
const char* tamebomberdesc =
|
|
"This bomberbird will follow you at some distance, and attack your enemies. "
|
|
"You can kill it to place a mine.";
|
|
|
|
const char *gargdesc =
|
|
"A being made of stone, who likes high buildings. It becomes normal stone when "
|
|
"killed, but only if next to something stable -- otherwise it falls.";
|
|
|
|
const char *lakeDesc = "Hell has these lakes everywhere... They are shaped like evil stars, and filled with burning sulphur.";
|
|
|
|
const char *thumpdesc = "A device that attracts sandworms and other enemies. You need to activate it.";
|
|
|
|
const char *twdesc = "This structure will disappear after some time.";
|
|
|
|
const char *jellydesc =
|
|
"Some of the Slime Beasts have decided to revolt against the color rules in the "
|
|
"Alchemist Lab. They have changed their shape and consistency, declared independence, and established their own Kingdom.\n\n"
|
|
"Jellies switch between being a wall and being a monster after every treasure you collect.";
|
|
|
|
const char *ruindesc =
|
|
"Once a beautiful city... but now overrun by the mighty Raiders of unknown origin.\n\n"
|
|
"Raiders cannot be harmed with mundane weapons, but each color has its movement restrictions.";
|
|
|
|
const char *rock_description =
|
|
"Shoot the Space Rocks for score. Large Rocks will split into two smaller rocks.";
|
|
|
|
#if HDR
|
|
enum eSlimegroup { sgNone, sgCave, sgWater, sgFloorA, sgFloorB, sgVine, sgTree };
|
|
#endif
|
|
|
|
#if HDR
|
|
// we use CF not MF to avoid confusion with MF_ movement flags
|
|
static constexpr flagtype CF_NOGHOST = Flag(0);
|
|
static constexpr flagtype CF_RAIDER = Flag(1);
|
|
static constexpr flagtype CF_PRINCESS = Flag(2);
|
|
static constexpr flagtype CF_MIMIC = Flag(3);
|
|
static constexpr flagtype CF_GOK = Flag(4);
|
|
static constexpr flagtype CF_NONLIVING = Flag(5);
|
|
static constexpr flagtype CF_METAL = Flag(6);
|
|
static constexpr flagtype CF_STUNNABLE = Flag(7);
|
|
static constexpr flagtype CF_HP = Flag(8);
|
|
static constexpr flagtype CF_MOUNTABLE = Flag(9);
|
|
static constexpr flagtype CF_FRIENDLY = Flag(10);
|
|
static constexpr flagtype CF_PLAYER = Flag(11);
|
|
static constexpr flagtype CF_BUG = Flag(12);
|
|
static constexpr flagtype CF_IVY = Flag(13);
|
|
static constexpr flagtype CF_PART = Flag(14);
|
|
static constexpr flagtype CF_MUTANTIVY = Flag(15);
|
|
static constexpr flagtype CF_ANYIVY = Flag(16);
|
|
static constexpr flagtype CF_BULLET = Flag(17);
|
|
static constexpr flagtype CF_DEMON = Flag(18);
|
|
static constexpr flagtype CF_WORM = Flag(19);
|
|
static constexpr flagtype CF_WITCH = Flag(20);
|
|
static constexpr flagtype CF_BIRD = Flag(21);
|
|
static constexpr flagtype CF_SLOWMOVER = Flag(22);
|
|
static constexpr flagtype CF_MAGNETIC = Flag(23);
|
|
static constexpr flagtype CF_SWITCH = Flag(24);
|
|
static constexpr flagtype CF_GHOST = Flag(25);
|
|
static constexpr flagtype CF_SHARK = Flag(26);
|
|
static constexpr flagtype CF_SLIME = Flag(27);
|
|
static constexpr flagtype CF_DRAGON = Flag(28);
|
|
static constexpr flagtype CF_KRAKEN = Flag(29);
|
|
static constexpr flagtype CF_NOBLOW = Flag(30);
|
|
static constexpr flagtype CF_MULTITILE = Flag(31);
|
|
static constexpr flagtype CF_LEADER = Flag(32);
|
|
static constexpr flagtype CF_FLYING = Flag(33);
|
|
static constexpr flagtype CF_ATTACK_THRU_VINE = Flag(34);
|
|
static constexpr flagtype CF_ATTACK_NONADJACENT = Flag(35);
|
|
static constexpr flagtype CF_NOHIGHLIGHT = Flag(36);
|
|
static constexpr flagtype CF_INACTIVE = Flag(37);
|
|
static constexpr flagtype CF_UNARMED = Flag(38);
|
|
static constexpr flagtype CF_IGNORE_PLATE = Flag(39);
|
|
static constexpr flagtype CF_BULL = Flag(40);
|
|
static constexpr flagtype CF_TROLL = Flag(41);
|
|
static constexpr flagtype CF_IGNORE_SMELL = Flag(42);
|
|
static constexpr flagtype CF_RATLING = Flag(43);
|
|
static constexpr flagtype CF_POWER = Flag(44);
|
|
static constexpr flagtype CF_GHOSTMOVER = Flag(45);
|
|
static constexpr flagtype CF_TECHNICAL = Flag(46);
|
|
static constexpr flagtype CF_MOVED = Flag(47);
|
|
static constexpr flagtype CF_FACING = Flag(48);
|
|
static constexpr flagtype CF_FACE_UP = Flag(49);
|
|
static constexpr flagtype CF_FACE_SIDE = Flag(50);
|
|
static constexpr flagtype CF_HIGH_THREAT = Flag(51);
|
|
static constexpr flagtype CF_SPAM = Flag(52);
|
|
|
|
enum eMonster {
|
|
#define MONSTER(a,b,c,d,e,f,g,h) d,
|
|
#include "content.cpp"
|
|
motypes
|
|
};
|
|
|
|
struct monstertype {
|
|
char glyph;
|
|
color_t color;
|
|
const char *name;
|
|
flagtype flags;
|
|
enum eMonster mgroup;
|
|
const char *help;
|
|
};
|
|
#endif
|
|
|
|
EX monstertype minf[motypes] = {
|
|
#define MONSTER(a,b,c,d,e,f,g,h) {a,b,c,e,g,h},
|
|
#include "content.cpp"
|
|
};
|
|
|
|
#if HDR
|
|
#define NUM_GS 8
|
|
struct genderswitch_t {
|
|
int gender;
|
|
eMonster m;
|
|
const char *name;
|
|
const char *desc;
|
|
};
|
|
#endif
|
|
|
|
EX genderswitch_t genderswitch[NUM_GS] = {
|
|
{ GEN_F, moFalsePrincess, "False Princess",
|
|
"Don't be fooled by this red-haired girl, or you will be stabbed if you come too close!"},
|
|
{ GEN_M, moFalsePrincess, "False Prince",
|
|
"Don't be fooled by this red-haired boy, or you will be stabbed if you come too close!"},
|
|
{ GEN_F, moRoseLady, "Rose Lady",
|
|
"This false princess is immune to the alluring scent of roses."},
|
|
{ GEN_M, moRoseLady, "Rose Lord",
|
|
"This false prince is immune to the alluring scent of roses."},
|
|
{ GEN_F, moRoseBeauty, "Rose Beauty",
|
|
"She has flowers in her long fair hair. You could not bring yourself to attack such a beautiful woman."},
|
|
{ GEN_M, moRoseBeauty, "Handsome Gardener",
|
|
"Tall, strong, and holding a flower in his hand. You could "
|
|
"not bring yourself to attack such a handsome man."},
|
|
{ GEN_F, moRusalka, "Rusałka",
|
|
"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."},
|
|
{ GEN_M, moRusalka, "Topielec",
|
|
"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."},
|
|
};
|
|
|
|
// --- items ---
|
|
|
|
#if HDR
|
|
enum eOrbshape { osNone, osLove, osRanged, osOffensive, osFriend, osUtility, osDirectional, osWarping, osFrog, osPowerUtility, osProtective, osMovement, osTerraform };
|
|
|
|
static constexpr flagtype ZERO = 0;
|
|
|
|
static constexpr flagtype IF_SHARD = Flag(0);
|
|
static constexpr flagtype IF_FIREPROOF = Flag(1);
|
|
static constexpr flagtype IF_PROTECTION = Flag(2);
|
|
static constexpr flagtype IF_EMPATHY = Flag(3);
|
|
static constexpr flagtype IF_RANGED = Flag(4);
|
|
static constexpr flagtype IF_SHMUPLIFE = Flag(5);
|
|
static constexpr flagtype IF_REVIVAL = Flag(6);
|
|
static constexpr flagtype IF_CURSE = Flag(7);
|
|
|
|
// 0 = basic treasure, 1 = other item, 2 = power orb, 3 = not an item
|
|
#define IC_TREASURE 0
|
|
#define IC_OTHER 1
|
|
#define IC_ORB 2
|
|
#define IC_NAI 3
|
|
|
|
struct itemtype {
|
|
char glyph;
|
|
color_t color;
|
|
const char *name;
|
|
int itemclass;
|
|
flagtype flags;
|
|
eOrbshape orbshape;
|
|
const char *help;
|
|
};
|
|
|
|
enum eItem {
|
|
#define ITEM(a,b,c,d,e,f,g,h,i) d,
|
|
#include "content.cpp"
|
|
ittypes
|
|
};
|
|
#endif
|
|
|
|
EX itemtype iinf[ittypes] = {
|
|
#define ITEM(a,b,c,d,e,f,g,h,i) {a,b,c,e,f,h,i},
|
|
#include "content.cpp"
|
|
};
|
|
|
|
// --- wall types ---
|
|
|
|
#if HDR
|
|
static constexpr flagtype WF_WATER = Flag(0);
|
|
static constexpr flagtype WF_BOAT = Flag(1);
|
|
static constexpr flagtype WF_CHASM = Flag(2);
|
|
static constexpr flagtype WF_NOFLIGHT = Flag(3);
|
|
static constexpr flagtype WF_FIRE = Flag(4);
|
|
static constexpr flagtype WF_THUMPER = Flag(5);
|
|
static constexpr flagtype WF_ACTIVABLE = Flag(6);
|
|
static constexpr flagtype WF_ALCHEMY = Flag(7);
|
|
static constexpr flagtype WF_RED = Flag(8);
|
|
static constexpr flagtype WF_WALL = Flag(9);
|
|
static constexpr flagtype WF_PUSHABLE = Flag(10);
|
|
static constexpr flagtype WF_CONE = Flag(11);
|
|
static constexpr flagtype WF_STDTREE = Flag(12);
|
|
static constexpr flagtype WF_GRAVE = Flag(13);
|
|
static constexpr flagtype WF_REPTILE = Flag(14);
|
|
static constexpr flagtype WF_HEATCOLOR = Flag(15);
|
|
static constexpr flagtype WF_HIGHWALL = Flag(16);
|
|
static constexpr flagtype WF_THORNY = Flag(17);
|
|
static constexpr flagtype WF_TIMEOUT = Flag(18);
|
|
static constexpr flagtype WF_CISLAND = Flag(19);
|
|
static constexpr flagtype WF_SULPHURIC = Flag(20);
|
|
static constexpr flagtype WF_HALFVINE = Flag(21);
|
|
static constexpr flagtype WF_NONBLOCK = Flag(22);
|
|
|
|
struct walltype {
|
|
char glyph;
|
|
color_t color;
|
|
const char *name;
|
|
flagtype flags;
|
|
int snakelevel;
|
|
eSlimegroup sg;
|
|
const char *help;
|
|
};
|
|
|
|
enum eWall {
|
|
#define WALL(a,b,c,d,e,f,g,h,i) d,
|
|
#include "content.cpp"
|
|
walltypes
|
|
};
|
|
#endif
|
|
|
|
EX walltype winf[walltypes] = {
|
|
#define WALL(a,b,c,d,e,f,g,h,i) {a,b,c,e,g,h,i},
|
|
#include "content.cpp"
|
|
};
|
|
|
|
// -- land types ---
|
|
|
|
#if HDR
|
|
enum eCanvasFloor { caflNone, caflM, caflFull, caflWarp, caflStar, caflCloud, caflCross, caflCharged,
|
|
caflSStar, caflOver, caflTri, caflFeather, caflBarrow, caflNew, caflTroll, caflButterfly, caflLava,
|
|
caflPalace, caflDemon, caflCave, caflDesert, caflPower, caflRose, caflTurtle, caflDragon, caflReptile,
|
|
caflHive, caflSwitch, caflTower, caflEND };
|
|
|
|
static constexpr flagtype LF_GENERATE_ALL = Flag(0);
|
|
static constexpr flagtype LF_ICY = Flag(1);
|
|
static constexpr flagtype LF_GRAVITY = Flag(2);
|
|
static constexpr flagtype LF_EQUI = Flag(3);
|
|
static constexpr flagtype LF_WARPED = Flag(4);
|
|
static constexpr flagtype LF_CYCLIC = Flag(5);
|
|
static constexpr flagtype LF_TECHNICAL = Flag(6);
|
|
static constexpr flagtype LF_MIRROR = Flag(7);
|
|
static constexpr flagtype LF_SEA = Flag(8);
|
|
static constexpr flagtype LF_COASTAL = Flag(9);
|
|
static constexpr flagtype LF_PURESEA = Flag(10);
|
|
static constexpr flagtype LF_ELEMENTAL = Flag(11);
|
|
static constexpr flagtype LF_HAUNTED = Flag(12);
|
|
static constexpr flagtype LF_TROLL = Flag(13);
|
|
static constexpr flagtype LF_INMIRROR = Flag(14);
|
|
static constexpr flagtype LF_INMIRRORORWALL = Flag(15);
|
|
static constexpr flagtype LF_ELECTRIC = Flag(17);
|
|
|
|
struct landtype {
|
|
color_t color;
|
|
const char *name;
|
|
flagtype flags;
|
|
eItem treasure;
|
|
const char *help;
|
|
};
|
|
|
|
enum eLand {
|
|
#define LAND(a,b,c,d,e,f,g) c,
|
|
#include "content.cpp"
|
|
landtypes
|
|
};
|
|
|
|
extern color_t floorcolors[landtypes];
|
|
#endif
|
|
|
|
EX const char *canvasFloorNames[caflEND] = {
|
|
"default", "smaller", "full", "warped", "star", "cloud", "cross", "charged",
|
|
"saloon", "overgrown", "triangle", "feather", "barrow", "elemental", "troll", "butterfly", "lava",
|
|
"palace", "demon", "cave", "desert", "power", "rose", "turtle", "dragon", "reptile",
|
|
"hive", "jelly", "tower"
|
|
};
|
|
|
|
EX const landtype linf[landtypes] = {
|
|
#define LAND(a,b,c,d,e,f,g) {a,b,d,e,g},
|
|
#include "content.cpp"
|
|
};
|
|
|
|
#if HDR
|
|
struct landtacinfo { eLand l; int tries, multiplier; };
|
|
#endif
|
|
|
|
EX vector<landtacinfo> land_tac = {
|
|
{laIce, 10, 1}, {laDesert, 10, 1},
|
|
{laHunting, 5, 2},
|
|
{laMotion, 10, 1}, {laCaves, 10, 1}, {laAlchemist, 10, 1},
|
|
{laJungle, 10, 1}, {laMirror, 10, 1}, {laZebra, 10, 1}, {laPalace, 10, 1},
|
|
{laOcean, 10, 1}, {laLivefjord, 10, 1}, {laWarpCoast, 10, 1}, {laRlyeh, 10, 1}, {laHell, 10, 1},
|
|
{laDryForest, 10, 1}, {laWineyard, 10, 1}, {laSwitch, 10, 1}, {laReptile, 10, 1},
|
|
{laDeadCaves, 10, 1}, {laGraveyard, 10, 1},
|
|
{laHaunted, 10, 1},
|
|
{laIvoryTower, 10, 1}, {laEndorian, 10, 1}, {laMountain, 5, 2}, {laDungeon, 5, 2},
|
|
{laRuins, 10, 1}, {laEmerald, 10, 1},
|
|
{laCocytus, 10, 1},
|
|
|
|
{laCaribbean, 5, 2}, {laWhirlpool, 5, 2}, {laKraken, 5, 2},
|
|
{laTemple, 5, 2}, {laMinefield, 5, 2},
|
|
{laPower, 5, 2}, {laHive, 5, 2}, {laRedRock, 5, 2}, {laStorms, 5, 2}, {laOvergrown, 5, 2},
|
|
{laClearing, 5, 2},
|
|
{laWhirlwind, 5, 2},
|
|
{laBlizzard, 10, 1},
|
|
{laRose, 5, 2}, {laVolcano, 10, 1}, {laDragon, 2, 5}, {laTortoise, 1, 10},
|
|
{laBurial, 5, 2},
|
|
{laElementalWall, 10, 1}, {laTrollheim, 5, 2},
|
|
{laPrairie, 5, 2}, {laBull, 5, 2}, {laTerracotta, 10, 1},
|
|
{laDice, 5, 2}, {laCursed, 5, 2},
|
|
|
|
{laCrossroads, 10, 1}, {laCrossroads2, 10, 1}, {laCrossroads3, 10, 1}, {laCrossroads4, 10, 1}, {laCrossroads5, 5, 2},
|
|
|
|
{laCamelot, 1, 100},
|
|
{laWildWest, 10, 1},
|
|
{laDual, 10, 1},
|
|
{laSnakeNest, 10, 1},
|
|
{laDocks, 10, 1},
|
|
|
|
{laBrownian, 10, 1},
|
|
{laVariant, 10, 1},
|
|
{laWestWall, 10, 1},
|
|
{laWet, 10, 1}, {laFrog, 10, 1}, {laEclectic, 10, 1},
|
|
};
|
|
|
|
EX vector<eLand> randlands = {
|
|
laIce, laDesert, laCaves, laAlchemist, laGraveyard, laPower, laLivefjord, laZebra,
|
|
laRlyeh, laDryForest, laEmerald, laWineyard, laDeadCaves, laRedRock,
|
|
laOvergrown, laWildWest, laWarpCoast, laRuins, laBull, laDragon, laReptile, laDocks,
|
|
laFrog, laWet, laZebra
|
|
};
|
|
|
|
#if HDR
|
|
enum eGeometry {
|
|
gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
|
|
gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,
|
|
gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron,
|
|
gBinary3, gCubeTiling, gCell120, gECell120, gRhombic3, gBitrunc3,
|
|
gSpace534, gSpace435,
|
|
gCell5,
|
|
gCell16, gECell16,
|
|
gCell8, gECell8,
|
|
gCell24, gECell24,
|
|
gCell600, gECell600,
|
|
gHoroTris, gHoroRec, gHoroHex,
|
|
gField435, gField534,
|
|
gBinary4, gSol,
|
|
gKiteDart2, gKiteDart3, gNil, gProduct, gRotSpace,
|
|
gTernary, gNIH, gSolN, gInfOrder, gSpace336, gSpace344, gCrystal344,
|
|
gArnoldCat, gArbitrary, gInfOrder4, gCrystal534,
|
|
gSpace535, gSpace536, gSeifertCover, gSeifertWeber, gHomologySphere,
|
|
gInfOrderMixed, gSpace436, gFake,
|
|
gSpace345, gSpace353, gSpace354, gSpace355,
|
|
gHalfBring,
|
|
gAperiodicHat,
|
|
gSierpinski3, gSierpinski4, gSixFlake, gMengerSponge, gSierpinskiTet,
|
|
gAperiodicSpectre,
|
|
gGUARD};
|
|
|
|
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSol, gcNIH, gcSolN, gcNil, gcProduct, gcSL2 };
|
|
|
|
enum class eVariation { bitruncated, pure, goldberg, irregular, dual, untruncated, warped, unrectified, subcubes, coxeter, dual_subcubes, bch, bch_oct };
|
|
|
|
typedef int modecode_t;
|
|
|
|
/** only the actual geometry */
|
|
struct geometryinfo1 {
|
|
/** geometry class */
|
|
eGeometryClass kind;
|
|
/** dimension of the gameplay (2 for crystal) */
|
|
int gameplay_dimension;
|
|
/** dimension of the graphics, may be greater than gameplay_dimension with vid.always3 on */
|
|
int graphical_dimension;
|
|
/** dimension of the homogeneous vector space used, usually graphical_dimension+1, but 3 in product */
|
|
int homogeneous_dimension;
|
|
/** signature of the scalar product used */
|
|
int sig[4];
|
|
};
|
|
|
|
struct geometryinfo {
|
|
std::string tiling_name;
|
|
std::string quotient_name;
|
|
const char* menu_displayed_name;
|
|
const char* shortname;
|
|
int sides;
|
|
int vertex;
|
|
flagtype flags;
|
|
geometryinfo1 g;
|
|
std::array<int,2> distlimit; // bitrunc, non-bitrunc
|
|
eVariation default_variation;
|
|
};
|
|
|
|
static constexpr flagtype qCLOSED = 1;
|
|
static constexpr flagtype qANYQ = 2;
|
|
static constexpr flagtype qNONORIENTABLE = 4;
|
|
static constexpr flagtype qSMALL = 8;
|
|
|
|
static constexpr flagtype qFIELD = 16;
|
|
static constexpr flagtype qDOCKS = 32;
|
|
static constexpr flagtype qZEBRA = 64;
|
|
|
|
static constexpr flagtype qELLIPTIC = 128;
|
|
|
|
static constexpr flagtype qBINARY = 256;
|
|
static constexpr flagtype qKITE = 512;
|
|
|
|
static constexpr flagtype qREGULAR = 1024; /* not set! */
|
|
static constexpr flagtype qARCHI = 2048;
|
|
static constexpr flagtype qHYBRID = 4096;
|
|
static constexpr flagtype qCRYSTAL = 8192;
|
|
static constexpr flagtype qSOL = 16384;
|
|
static constexpr flagtype qEXPERIMENTAL = 32768;
|
|
static constexpr flagtype qNIH = 65536;
|
|
|
|
static constexpr flagtype qIDEAL = 131072;
|
|
static constexpr flagtype qHUGE_BOUNDED = 262144;
|
|
static constexpr flagtype qOPTQ = Flag(19);
|
|
static constexpr flagtype qSINGLE = Flag(20);
|
|
|
|
static constexpr flagtype qDEPRECATED = Flag(21);
|
|
static constexpr flagtype qINFMIXED = Flag(22);
|
|
|
|
static constexpr flagtype qRAYONLY = Flag(23);
|
|
static constexpr flagtype qAFFINE = Flag(24);
|
|
|
|
static constexpr flagtype qULTRA = Flag(25);
|
|
|
|
static constexpr flagtype qPORTALSPACE = Flag(26);
|
|
|
|
static constexpr flagtype qSTRETCHABLE = Flag(27);
|
|
|
|
static constexpr flagtype qCAT = Flag(28);
|
|
|
|
static constexpr flagtype qAPERIODIC = Flag(29);
|
|
static constexpr flagtype qHAT = Flag(30);
|
|
|
|
static constexpr flagtype qFRACTAL = Flag(31);
|
|
|
|
// note: dnext assumes that x&7 equals 7
|
|
static constexpr int SEE_ALL = 50;
|
|
// note: check_football_colorability in arbitrile.cpp assumes OINF is divisible by 3
|
|
static constexpr int OINF = 123;
|
|
|
|
extern eGeometry geometry;
|
|
extern eVariation variation;
|
|
#endif
|
|
|
|
#if HDR
|
|
static constexpr flagtype qsNONOR = qANYQ | qSMALL | qCLOSED | qNONORIENTABLE;
|
|
static constexpr flagtype qsNONORE = qsNONOR | qELLIPTIC;
|
|
static constexpr flagtype qsBQ = qANYQ | qSMALL | qCLOSED;
|
|
static constexpr flagtype qsSMALL = qANYQ | qSMALL | qCLOSED;
|
|
static constexpr flagtype qsSMALLN = qANYQ | qSMALL | qCLOSED | qNONORIENTABLE;
|
|
static constexpr flagtype qsZEBRA = qANYQ | qSMALL | qCLOSED | qZEBRA;
|
|
static constexpr flagtype qsFIELD = qANYQ | qFIELD | qCLOSED;
|
|
static constexpr flagtype qsDOCKS = qANYQ | qSMALL | qCLOSED | qDOCKS;
|
|
static constexpr flagtype qsSMALLB = qSMALL | qCLOSED;
|
|
static constexpr flagtype qsSMALLBF = qsSMALLB | qsFIELD | qANYQ;
|
|
static constexpr flagtype qsSMALLBE = qsSMALLB | qELLIPTIC | qANYQ;
|
|
static constexpr flagtype qsBP = qBINARY | qKITE;
|
|
|
|
static constexpr flagtype qsSINGLE = qANYQ | qSMALL | qCLOSED | qSINGLE;
|
|
#endif
|
|
|
|
EX geometryinfo1 giEuclid2 = { gcEuclid, 2, 2, 3, {1,1, 0,0 } };
|
|
EX geometryinfo1 giHyperb2 = { gcHyperbolic, 2, 2, 3, {1,1,-1,0 } };
|
|
EX geometryinfo1 giSphere2 = { gcSphere, 2, 2, 3, {1,1,+1,0 } };
|
|
|
|
EX geometryinfo1 giEuclid3 = { gcEuclid, 3, 3, 4, {1,1, 1,0 } };
|
|
EX geometryinfo1 giHyperb3 = { gcHyperbolic, 3, 3, 4, {1,1, 1,-1} };
|
|
EX geometryinfo1 giSphere3 = { gcSphere, 3, 3, 4, {1,1, 1,+1} };
|
|
|
|
EX geometryinfo1 giSol = { gcSol, 3, 3, 4, {1,1, 1,0 } };
|
|
EX geometryinfo1 giNIH = { gcNIH, 3, 3, 4, {1,1, 1,0 } };
|
|
EX geometryinfo1 giSolN = { gcSolN, 3, 3, 4, {1,1, 1,0 } };
|
|
|
|
EX geometryinfo1 giNil = { gcNil, 3, 3, 4, {1,1, 1,0 } };
|
|
EX geometryinfo1 giProductH= { gcProduct, 3, 3, 3, {1,1,-1,0 } };
|
|
EX geometryinfo1 giProductS= { gcProduct, 3, 3, 3, {1,1, 1,0 } };
|
|
EX geometryinfo1 giProduct = { gcProduct, 3, 3, 3, {1,1, 1,0 } /* will be filled in product::configure() */ };
|
|
EX geometryinfo1 giSL2 = { gcSL2, 3, 3, 4, {1,1,-1,-1} };
|
|
|
|
EX modecode_t no_code = 0x1;
|
|
|
|
/** list of available geometries */
|
|
EX vector<geometryinfo> ginf = {
|
|
{"{7,3}", "none", "{7,3} (standard HyperRogue map)", "HR", 7, 3, 0, giHyperb2, {{7, 5}}, eVariation::bitruncated},
|
|
{"{6,3}", "none", "{6,3} (euclidean Hex grid)", "euclid", 6, 3, qOPTQ, giEuclid2, {{7, 7}}, eVariation::bitruncated},
|
|
{"{5,3}", "none", "{5,3} (dodecahedron)", "sphere", 5, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
|
{"{5,3}", "elliptic", "elliptic geometry in {5,3}", "elliptic", 5, 3, qsNONORE, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
|
{"{7,3}", "Zebra", "Zebra quotient", "Zebra", 7, 3, qsZEBRA, giHyperb2, {{7, 5}}, eVariation::bitruncated},
|
|
{"{7,3}", "field", "field quotient", "field", 7, 3, qsFIELD, giHyperb2, {{7, 5}}, eVariation::bitruncated},
|
|
{"{6,3}", "torus", "torus/Klein bottle/...", "torus", 6, 3, qsBQ|qDEPRECATED, giEuclid2, {{7, 7}}, eVariation::bitruncated},
|
|
{"{8,3}", "none", "{8,3} (like standard but with octagons)", "oct", 8, 3, 0, giHyperb2, {{6, 4}}, eVariation::bitruncated},
|
|
{"{5,4}", "none", "{5,4} (four pentagons)", "4x5", 5, 4, 0, giHyperb2, {{6, 4}}, eVariation::bitruncated},
|
|
{"{6,4}", "none", "{6,4} (four hexagons)", "4x6", 6, 4, 0, giHyperb2, {{5, 3}}, eVariation::bitruncated},
|
|
{"{7,4}", "none", "{7,4} (four heptagons)", "4x7", 7, 4, 0, giHyperb2, {{4, 3}}, eVariation::bitruncated},
|
|
{"{4,3}", "none", "{4,3} (cube)", "3x4", 4, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
|
{"{3,3}", "none", "{3,3} (tetrahedron)", "3x3", 3, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
|
{"{4,4}", "none", "{4,4} (Euclidean square grid)", "4x4", 4, 4, qOPTQ, giEuclid2, {{7, 7}}, eVariation::bitruncated},
|
|
{"{4,3}", "elliptic", "elliptic geometry in {4,3}", "e3x4", 4, 3, qsNONORE, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
|
{"{7,3}", "Klein", "Klein Quartic", "Klein", 7, 3, qsSMALL, giHyperb2, {{7, 5}}, eVariation::bitruncated},
|
|
{"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, giHyperb2, {{6, 4}}, eVariation::bitruncated},
|
|
{"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, giHyperb2, {{6, 4}}, eVariation::bitruncated},
|
|
{"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, giHyperb2, {{7, 5}}, eVariation::bitruncated},
|
|
{"binary","none", "variant of the binary tiling", "binary", 7, 3, qBINARY, giHyperb2, {{7, 5}}, eVariation::pure},
|
|
{"Arch", "none", "Archimedean", "A", 7, 3, qARCHI, giHyperb2, {{7, 5}}, eVariation::pure},
|
|
{"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, giHyperb2, {{7, 5}}, eVariation::bitruncated},
|
|
{"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, giHyperb2, {{6, 4}}, eVariation::bitruncated},
|
|
{"{12,3}","M3", "Schmutz's M(3)", "M3", 12, 3, qsSMALL, giHyperb2, {{4, 2}}, eVariation::bitruncated},
|
|
{"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, giHyperb2, {{4, 2}}, eVariation::bitruncated},
|
|
{"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ|qCRYSTAL, giHyperb2, {{5, 3}}, eVariation::pure},
|
|
{"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
|
|
{"bin{4,4}", "none", "{4,4} on horospheres", "bin44", 9, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"{4,3,4}","none", "{4,3,4} cube tiling", "434", 6, 4, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
|
|
{"{5,3,3}","none", "{5,3,3} 120-cell", "533", 12, 3, qsSMALLB | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{5,3,3}", "elliptic","{5,3,3} 120-cell (elliptic space)", "e533", 12, 3, qsSMALLBE | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"rh{4,3,4}","none", "rhombic dodecahedral honeycomb", "rh434", 12, 3, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
|
|
{"2t{4,3,4}","none", "bitruncated cubic honeycomb", "2t434", 14, 3, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
|
|
{"{5,3,4}","none", "{5,3,4} hyperbolic honeycomb", "534", 12, 4, 0, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{4,3,5}","none", "{4,3,5} hyperbolic honeycomb", "435", 6, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,3,3}","none", "{3,3,3} 5-cell", "333", 4, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{3,3,4}","none", "{3,3,4} 16-cell", "334", 4, 4, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{3,3,4}","elliptic","{3,3,4} 16-cell (elliptic space)", "e334", 4, 4, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{4,3,3}","none", "{4,3,3} 8-cell", "433", 6, 4, qsSMALLB | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{4,3,3}","elliptic","{4,3,3} 8-cell (elliptic space)", "e433", 6, 4, qsSMALLBE | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{3,4,3}","none", "{3,4,3} 24-cell", "343", 8, 3, qsSMALLB | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{3,4,3}","elliptic","{3,4,3} 24-cell (elliptic space)", "e343", 8, 3, qsSMALLBE | qSTRETCHABLE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{3,3,5}","none", "{3,3,5} 600-cell", "335", 4, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{3,3,5}","elliptic","{3,3,5} 600-cell (elliptic space)", "e335", 4, 3, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"bin{3,6}", "none", "{3,6} on horospheres", "bin36", 8, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"bin-rect", "none", "rectangles on horospheres", "bin44/2", 7, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"bin{6,3}", "none", "{6,3} on horospheres", "bin63", 14, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"{4,3,5}","field", "{4,3,5} field quotient space", "f435", 6, 5, qsSMALLBF | qDEPRECATED, giHyperb3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"{5,3,4}","field", "{5,3,4} field quotient space", "f435", 12, 4, qsSMALLBF | qDEPRECATED, giHyperb3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
|
|
{"binary4","none", "standard binary tiling", "binary4", 5, 3, qBINARY, giHyperb2, {{7, 5}}, eVariation::pure},
|
|
{"sol", "none", "Solv geometry", "sol", 8, 3, qBINARY|qSOL, giSol, {{7, 5}}, eVariation::pure},
|
|
{"kd2", "none", "kite-and-dart", "kd2", 4, 3, qKITE | qAPERIODIC, giEuclid2, {{7, 7}}, eVariation::pure},
|
|
{"kd3", "none", "kite-and-dart on horospheres", "kd3", 12, 3, qsBP, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"nil", "none", "Nil geometry", "nil", 6, 3, qOPTQ, giNil, {{7, 5}}, eVariation::pure},
|
|
{"product","none", "product space", "product", 7, 3, qHYBRID, giProduct, {{7, 3}}, eVariation::pure},
|
|
{"twisted","none", "rotation space", "twisted", 7, 3, qHYBRID, giSL2, {{6, 4}}, eVariation::pure},
|
|
{"ternary","none", "standard ternary tiling", "ternary", 6, 3, qBINARY, giHyperb2, {{6, 4}}, eVariation::pure},
|
|
{"3x2", "none", "stretched hyperbolic", "3:2", 11, 3, qBINARY|qNIH, giNIH, {{6, 3}}, eVariation::pure},
|
|
{"3x1/2", "none", "stretched Solv", "3:1/2", 9, 3, (qBINARY|qSOL|qNIH), giSolN, {{7, 3}}, eVariation::pure},
|
|
{"{3,oo}", "none", "{3,∞} (infinite triangles)", "oox3", 3, OINF, qIDEAL, giHyperb2, {{7, 7}}, eVariation::pure},
|
|
{"{3,3,6}","none", "{3,3,6} hyperbolic honeycomb", "336", 4, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,4,4}","none", "{3,4,4} hyperbolic honeycomb", "344", 8, 4, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,4,4}","Crystal", "4D crystal in H3", "Cryst3" , 8, 4, qIDEAL | qANYQ | qCRYSTAL, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"cat", "cat", "Arnold's cat mapping torus", "cat", 12, 3, qBINARY | qSOL | qsBQ | qOPTQ | qCAT, giSol, {{6, 4}}, eVariation::pure},
|
|
{"file", "none", "load from file", "file", 7, 3, 0, giEuclid2, {{7, 5}}, eVariation::pure},
|
|
{"{4,oo}", "none", "{4,∞} (infinite squares)", "oox4", 4, OINF, qIDEAL, giHyperb2, {{5, 5}}, eVariation::pure},
|
|
{"{5,3,4}","Crystal", "6D crystal in H3", "Cryst6" , 12, 4, qANYQ | qCRYSTAL, giHyperb3, {{7, 3}}, eVariation::pure},
|
|
{"{5,3,5}","none", "{5,3,5} hyperbolic honeycomb", "535", 12, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{5,3,6}","none", "{5,3,6} hyperbolic honeycomb", "536", 12, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{5,3,5}","SWh", "{5,3,5} quotient", "535c", 12, 5, qsSMALLB | qANYQ, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{5,3,5}","SW", "Seifert-Weber space", "535s", 12, 5, qsSINGLE, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{5,3,3}","SW", "Poincaré homology sphere", "533s", 12, 3, qsSINGLE, giSphere3, {{7, 2}}, eVariation::pure},
|
|
{"{?,oo}", "none", "{3/4,∞} (infinite triangles and squares)", "ooxm", 3, OINF, qIDEAL | qINFMIXED, giHyperb2, {{6, 6}}, eVariation::pure},
|
|
{"{4,3,6}","none", "{4,3,6} hyperbolic honeycomb", "436", 6, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"?", "none", "fake", "", 0, 0, qRAYONLY, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,4,5}","none", "{3,4,5} hyperbolic honeycomb", "345", 8, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,5,3}","none", "{3,5,3} hyperbolic honeycomb", "353", 20, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,5,4}","none", "{3,5,4} hyperbolic honeycomb", "354", 20, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{3,5,5}","none", "{3,5,5} hyperbolic honeycomb", "355", 20, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
|
|
{"{5,4}", "pBring", "projective Bring's Surface", "pBring", 5, 4, qsSMALLN, giHyperb2, {{6, 4}}, eVariation::bitruncated},
|
|
{"hat", "none", "aperiodic hat", "hat", 14, 3, qAPERIODIC | qHAT, giEuclid2, {{7, 7}}, eVariation::pure},
|
|
{"triangle","none", "Sierpiński triangle", "S3", 6, 3, qFRACTAL, giEuclid2, {{10, 10}}, eVariation::pure},
|
|
{"carpet", "none", "Sierpiński carpet", "S4", 4, 4, qFRACTAL, giEuclid2, {{10, 10}}, eVariation::pure},
|
|
{"6-flake","none", "6-flake fractal", "S6", 6, 3, qFRACTAL, giEuclid2, {{10, 10}}, eVariation::pure},
|
|
{"{4,3,4}","none", "Menger sponge", "S8", 6, 4, qFRACTAL, giEuclid3, {{10, 10}}, eVariation::pure},
|
|
{"rh{4,3,4}","none", "Sierpiński tetrahedron", "S4b", 12, 3, qFRACTAL, giEuclid3, {{10, 10}}, eVariation::pure},
|
|
{"spectre","none", "aperiodic spectre", "spectre", 14, 3, qAPERIODIC | qHAT, giEuclid2, {{7, 7}}, eVariation::pure},
|
|
};
|
|
// bits: 9, 10, 15, 16, (reserved for later) 17, 18
|
|
|
|
#if HDR
|
|
namespace mf {
|
|
static constexpr flagtype azimuthal = 1;
|
|
static constexpr flagtype cylindrical = 2; /* usually you want 'band' */
|
|
static constexpr flagtype equiarea = 4;
|
|
static constexpr flagtype equidistant = 8;
|
|
static constexpr flagtype conformal = 16;
|
|
static constexpr flagtype euc_boring = 32;
|
|
static constexpr flagtype space = 64;
|
|
static constexpr flagtype hyper_only = 128;
|
|
static constexpr flagtype hyper_or_torus = 256;
|
|
static constexpr flagtype pseudocylindrical = 512; /* includes cylindrical; usually you want 'band' or 'pseudoband' */
|
|
static constexpr flagtype equivolume = 1024;
|
|
static constexpr flagtype twopoint = 2048;
|
|
static constexpr flagtype uses_bandshift = 4096;
|
|
static constexpr flagtype broken = 8192; /* in spherical case, these are broken along the meridian 180 deg */
|
|
static constexpr flagtype technical = 16384; /* don't display in the list */
|
|
static constexpr flagtype product_special = (1<<15);
|
|
static constexpr flagtype axial = (1<<16);
|
|
static constexpr flagtype perspective = (1<<17);
|
|
static constexpr flagtype orientation = (1<<18);
|
|
static constexpr flagtype transition = (1<<19);
|
|
static constexpr flagtype werner = (1<<20);
|
|
static constexpr flagtype horocyclic = (1<<21);
|
|
|
|
static constexpr flagtype band = (cylindrical | pseudocylindrical | uses_bandshift | orientation);
|
|
static constexpr flagtype pseudoband = (pseudocylindrical | uses_bandshift | orientation);
|
|
}
|
|
|
|
struct modelinfo {
|
|
const char *name_hyperbolic;
|
|
const char *name_euclidean;
|
|
const char *name_spherical;
|
|
|
|
flagtype flags;
|
|
};
|
|
|
|
enum eModel : int {
|
|
mdDisk, mdHalfplane, mdBand, mdPolygonal, mdFormula,
|
|
// 5..8.
|
|
mdEquidistant, mdEquiarea, mdBall, mdHyperboloid,
|
|
// 9..13
|
|
mdHemisphere, mdBandEquidistant, mdBandEquiarea, mdSinusoidal, mdTwoPoint,
|
|
// 14..16
|
|
mdFisheye, mdJoukowsky, mdJoukowskyInverted,
|
|
// 17..19
|
|
mdRotatedHyperboles, mdSpiral, mdPerspective,
|
|
// 20..24
|
|
mdEquivolume, mdCentralInversion, mdSimulatedPerspective, mdTwoHybrid, mdGeodesic,
|
|
// 25..27
|
|
mdMollweide, mdCentralCyl, mdCollignon,
|
|
// 28..31
|
|
mdHorocyclic, mdQuadrant, mdAxial, mdAntiAxial,
|
|
// 32..38
|
|
mdWerner, mdAitoff, mdHammer, mdLoximuthal, mdMiller, mdGallStereographic, mdWinkelTripel,
|
|
// 39..48
|
|
mdPoorMan, mdPanini, mdRetroCraig, mdRetroLittrow, mdRetroHammer, mdThreePoint, mdLiePerspective, mdLieOrthogonal, mdRelPerspective, mdRelOrthogonal,
|
|
// 49..50
|
|
mdHorocyclicEqa, mdConformalSquare,
|
|
// 51..
|
|
mdGUARD, mdPixel, mdHyperboloidFlat, mdPolynomial, mdManual
|
|
};
|
|
#endif
|
|
|
|
// remember to match the following mask when specifying codes for extra geometries: 0x78600
|
|
// (other bits are used for other information)
|
|
|
|
#define X3(x) x, x, x
|
|
|
|
/** list of available models (i.e., projections) */
|
|
EX vector<modelinfo> mdinf = {
|
|
{"disk/Gans", "general perspective", "general perspective", mf::azimuthal | mf::conformal},
|
|
{"half-plane", "inversion", "stereographic projection [VR]", mf::conformal | mf::orientation | mf::horocyclic},
|
|
{"band", "band", "Mercator", mf::band | mf::conformal | mf::transition},
|
|
{X3("polygonal"), mf::conformal | mf::orientation},
|
|
{X3("formula"), 0},
|
|
{X3("azimuthal equidistant"), mf::azimuthal | mf::equidistant | mf::euc_boring | mf::product_special},
|
|
{X3("azimuthal equi-area"), mf::azimuthal | mf::equiarea | mf::euc_boring},
|
|
{X3("ball model"), mf::conformal | mf::azimuthal | mf::space},
|
|
{"Minkowski hyperboloid", "plane", "sphere", mf::conformal | mf::space | mf::euc_boring},
|
|
{"hemisphere", "sphere", "Minkowski hyperboloid", mf::conformal | mf::space},
|
|
{X3("band equidistant"), mf::band | mf::equidistant | mf::euc_boring},
|
|
{X3("band equi-area"), mf::band | mf::equiarea | mf::euc_boring},
|
|
{X3("sinusoidal"), mf::pseudoband | mf::equiarea | mf::euc_boring},
|
|
{X3("two-point equidistant"), mf::equidistant | mf::euc_boring | mf::twopoint | mf::orientation},
|
|
{X3("fisheye"), 0},
|
|
{X3("Joukowsky transform"), mf::hyper_only | mf::conformal | mf::transition | mf::orientation},
|
|
{X3("Joukowsky+inversion"), mf::hyper_only | mf::conformal | mf::transition | mf::orientation},
|
|
{X3("rotated hyperboles"), mf::hyper_only | mf::orientation},
|
|
{X3("spiral/ring"), mf::hyper_or_torus | mf::uses_bandshift | mf::orientation},
|
|
{X3("native perspective"), mf::perspective | mf::product_special},
|
|
{X3("azimuthal equi-volume"), mf::azimuthal | mf::equivolume | mf::euc_boring},
|
|
{X3("central inversion"), mf::azimuthal | mf::conformal},
|
|
{X3("two-point azimuthal"), mf::euc_boring | mf::azimuthal | mf::twopoint | mf::orientation},
|
|
{X3("two-point hybrid"), mf::euc_boring | mf::azimuthal | mf::equidistant | mf::twopoint | mf::orientation},
|
|
{X3("geodesic"), mf::perspective | mf::product_special},
|
|
{X3("Mollweide"), mf::euc_boring | mf::pseudoband | mf::equiarea},
|
|
{X3("central cylindrical"), mf::euc_boring | mf::band},
|
|
{X3("Collignon"), mf::pseudoband | mf::equiarea},
|
|
{X3("horocyclic coordinates"), mf::euc_boring | mf::orientation | mf::horocyclic},
|
|
{X3("quadrant coordinates"), mf::euc_boring | mf::orientation},
|
|
{X3("axial coordinates"), mf::euc_boring | mf::transition | mf::orientation},
|
|
{X3("anti-axial coordinates"), mf::euc_boring | mf::orientation},
|
|
{X3("Werner projection"), mf::euc_boring | mf::broken | mf::werner | mf::orientation}, // keep distances from pole, and distances along parallels
|
|
{X3("Aitoff projection"), mf::euc_boring | mf::broken | mf::orientation}, // halve longitudes, do azequid, double x
|
|
{X3("Hammer projection"), mf::euc_boring | mf::broken | mf::orientation}, // halve longitudes, do azequia, double x
|
|
{X3("loximuthal projection"), mf::euc_boring | mf::broken | mf::orientation}, // map loxodromes azimuthally and equidistantly
|
|
{X3("Miller projection"), mf::euc_boring | mf::band}, // scale latitude 4/5 -> Mercator -> 5/4
|
|
{X3("Gall stereographic"), mf::euc_boring | mf::band}, // like central cylindrical but stereographic
|
|
{X3("Winkel tripel"), mf::euc_boring | mf::broken | mf::orientation}, // mean of equirec and Aitoff
|
|
{X3("Poor man's square"), mf::euc_boring | mf::orientation}, // https://archive.bridgesmathart.org/2018/bridges2018-59.html
|
|
{X3("Panini projection"), mf::euc_boring | mf::orientation},
|
|
{X3("Craig retroazimuthal"), mf::euc_boring | mf::broken | mf::pseudoband}, // retroazimuthal cylindrical
|
|
{X3("Littrow retroazimuthal"), mf::euc_boring | mf::broken | mf::pseudoband}, // retroazimuthal conformal
|
|
{X3("Hammer retroazimuthal"), mf::euc_boring | mf::pseudoband}, // retroazimuthal equidistant
|
|
{X3("three-point equidistant"), mf::euc_boring | mf::equidistant | mf::orientation | mf::product_special | mf::twopoint},
|
|
{X3("Lie perspective"), mf::euc_boring | mf::perspective},
|
|
{X3("Lie orthogonal"), mf::euc_boring},
|
|
{X3("relativistic perspective"), mf::euc_boring | mf::perspective},
|
|
{X3("relativistic orthogonal"), mf::euc_boring},
|
|
{X3("horocyclic equal-area"), mf::euc_boring | mf::equiarea | mf::orientation | mf::horocyclic},
|
|
{X3("conformal square"), mf::orientation | mf::broken | mf::transition},
|
|
{X3("guard"), mf::technical},
|
|
{X3("pixel"), mf::technical},
|
|
{X3("hypflat"), mf::technical},
|
|
{X3("polynomial"), mf::technical | mf::conformal | mf::orientation},
|
|
{X3("manual"), mf::technical},
|
|
};
|
|
|
|
#undef X3
|
|
|
|
#if HDR
|
|
static inline bool orbProtection(eItem it) { return false; } // not implemented
|
|
|
|
// these markers use lands which never appear on barrier sides
|
|
|
|
const eLand NOWALLSEP = laNone;
|
|
const eLand NOWALLSEP_SWAP = laMountain;
|
|
const eLand NOWALLSEP_WALL = laHauntedWall;
|
|
const eLand NOWALLSEP_USED = laWhirlpool;
|
|
const eLand NOWALLSEP_WALL_CPOS = laBarrier;
|
|
const eLand NOWALLSEP_WALL_CNEG = laOceanWall;
|
|
const eLand NOWALLSEP_WALL_EPOS = laClearing;
|
|
const eLand NOWALLSEP_WALL_ENEG = laPrincessQuest;
|
|
|
|
#endif
|
|
|
|
}
|