update to 9.4k

This commit is contained in:
Zeno Rogue 2017-05-31 18:33:50 +02:00
parent c6397f9df0
commit c2cff957cf
15 changed files with 1759 additions and 173 deletions

View File

@ -519,7 +519,7 @@ void improveItemScores() {
void achievement_final(bool really_final) {
if(offlineMode) return;
#ifdef HAVE_ACHIEVEMENTS
// upload_score(LB_STATISTICS, time(NULL));
upload_score(LB_STATISTICS, time(NULL));
if(cheater) return;
#ifdef TOUR
if(tour::on) return;
@ -599,6 +599,7 @@ void achievement_final(bool really_final) {
}
void achievement_victory(bool hyper) {
DEBB(DF_STEAM, (debugfile,"achievement_victory\n"))
if(offlineMode) return;
#ifdef HAVE_ACHIEVEMENTS
if(cheater) return;
@ -611,6 +612,7 @@ void achievement_victory(bool hyper) {
if(yendor::on) return;
if(tactic::on) return;
if(chaosmode) return;
DEBB(DF_STEAM, (debugfile,"after checks\n"))
int t = savetime + time(NULL) - timerstart;
@ -656,6 +658,7 @@ void achievement_victory(bool hyper) {
}
}
DEBB(DF_STEAM, (debugfile, "uploading scores\n"))
upload_score(ih1, t);
upload_score(ih2, turncount);
#endif

View File

@ -1101,6 +1101,7 @@ namespace mirror {
}
void destroyStray() {
if(geometry == gQuotient2) return;
for(int i=0; i<size(mirrors2); i++) {
cell *c = mirrors2[i];
if(c->cpdist > 7 && isMimic(c)) {

View File

@ -2738,6 +2738,12 @@ void bfs() {
buildAirmap();
if(overgenerate) doOvergenerate();
if(geometry == gQuotient2) {
mirrors.clear();
for(cell *c: currentmap->allcells())
if(isMimic(c)) mirrors.push_back(c);
}
}
bool makeEmpty(cell *c) {

View File

@ -213,6 +213,9 @@ namespace shmup {
bool playerInBoat(int i);
void destroyBoats(cell *c);
bool boatAt(cell *c);
void virtualRebase(cell*& base, transmatrix& at, bool tohex);
void virtualRebase(shmup::monster *m, bool tohex);
}
// graph
@ -753,7 +756,8 @@ bool hasSafeOrb(cell *c);
void placeWater(cell *c, cell *c2);
bool againstCurrent(cell *w, cell *from);
#define DEFAULTCONTROL (multi::players == 1 && !shmup::on && !multi::alwaysuse)
#define DEFAULTCONTROL (multi::players == 1 && !shmup::on && !multi::alwaysuse)
#define DEFAULTNOR(sym) (DEFAULTCONTROL || multi::notremapped(sym))
extern bool timerghost;
@ -1194,3 +1198,4 @@ string turnstring(int i);
int celldistance(cell *c1, cell *c2);
bool behindsphere(const transmatrix& V);
extern hyperpoint pirateCoords;

View File

@ -1,8 +1,8 @@
id ICON "hr-icon.ico"
1 VERSIONINFO
FILEVERSION 9,4,0,7
PRODUCTVERSION 9,4,0,7
FILEVERSION 9,4,0,11
PRODUCTVERSION 9,4,0,11
BEGIN
BLOCK "StringFileInfo"
BEGIN
@ -10,12 +10,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Zeno Rogue"
VALUE "FileDescription", "A roguelike in non-euclidean space"
VALUE "FileVersion", "83"
VALUE "FileVersion", "94k"
VALUE "InternalName", "hyper"
VALUE "LegalCopyright", "Zeno Rogue"
VALUE "OriginalFilename", "hyper.exe"
VALUE "ProductName", "HyperRogue"
VALUE "ProductVersion", "9.4g"
VALUE "ProductVersion", "9.4k"
END
END

View File

@ -81,6 +81,11 @@ const hyperpoint Cx1 = { {1,0,1.41421356237} };
// also used to verify whether a point h1 is on the hyperbolic plane by using Hypc for h2
ld intval(const hyperpoint &h1, const hyperpoint &h2) {
if(elliptic) {
double d1 = squar(h1[0]-h2[0]) + squar(h1[1]-h2[1]) + squar(h1[2]-h2[2]);
double d2 = squar(h1[0]+h2[0]) + squar(h1[1]+h2[1]) + squar(h1[2]+h2[2]);
return min(d1, d2);
}
return squar(h1[0]-h2[0]) + squar(h1[1]-h2[1]) + (sphere?1:euclid?0:-1) * squar(h1[2]-h2[2]);
}
@ -379,7 +384,11 @@ transmatrix inverse(transmatrix T) {
// distance between mh and 0
double hdist0(const hyperpoint& mh) {
if(sphere) return mh[2] >= 1 ? 0 : mh[2] <= -1 ? M_PI : acos(mh[2]);
if(sphere) {
ld res = mh[2] >= 1 ? 0 : mh[2] <= -1 ? M_PI : acos(mh[2]);
if(elliptic && res > M_PI/2) res = 2*M_PI-res;
return res;
}
if(!euclid && mh[2] > 1.5) return acosh(mh[2]);
ld d = sqrt(mh[0]*mh[0]+mh[1]*mh[1]);
if(euclid) return d;

View File

@ -1,6 +1,6 @@
#define VER "9.4j"
#define VERNUM 9410
#define VERNUM_HEX 0x9410
#define VER "9.4k"
#define VERNUM 9411
#define VERNUM_HEX 0x9411
#define GEN_M 0
#define GEN_F 1

View File

@ -5691,8 +5691,7 @@ namespace halloween {
cell *farempty(bool lastresort = false) {
int maxdist = 0;
cell* validcells[100];
int qvc = 0;
vector<cell*> validcells;
int firstfar1 = 0;
for(int i=1; i<size(dcal); i++) {
bool okay =
@ -5701,12 +5700,13 @@ namespace halloween {
okay = dcal[i]->wall != waChasm && !isMultitile(dcal[i]->monst);
if(okay) {
if(dcal[i]->cpdist > maxdist)
firstfar1 = qvc,
firstfar1 = size(validcells),
maxdist = dcal[i]->cpdist;
validcells[qvc++] = dcal[i];
validcells.push_back(dcal[i]);
}
}
int qvc = size(validcells);
if(qvc == firstfar1) return farempty(true);
return validcells[firstfar1 + hrand(qvc - firstfar1)];

View File

@ -5007,4 +5007,507 @@ S("compass size", "velikost kompasu")
"NEW_ACHIEVEMENT_8_18_DESC" "Poraž Písečného červa v geometrii Zebra kvocientu."
*/
N("Tortoise", GEN_F, "Želva", "Želvy", "Želva", "Želvou")
S("line patterns", "vzory čar")
S("1 turn", "1 kolo")
S("%1 turns", "kola: %1")
S("items/kills mode", "mód předmětů/zabitých netvorů")
S("images", "obrázky")
S("letters", "písmena")
S("input", "vstup")
S("default", "default")
S("config", "konfigurace")
S("expansion", "rozšíření")
S("continue", "pokračuj")
S("main menu", "hlavní menu")
S("restart", "nová hra")
S("quit", "konec")
S("exit menu", "opusť menu")
S(
"A tourist from another world. They mutter something about the 'tutorial', "
"and claim that they are here just to learn, and to leave without any treasures. "
"Do not kill them!",
"Turista z jiného světa. Mumlá něco o 'tutoriálu' a tvrdí, že se jenom učí "
"a odejde bez pokladů. Nezabíjet!")
S(
"This monster has come from another world, presumably to steal our treasures. "
"Not as fast as an Eagle, not as resilient as the guards from the Palace, "
"and not as huge as the Mutant Ivy from the Clearing; however, "
"they are very dangerous because of their intelligence, "
"and access to magical powers.\n\n",
"Tento netvor přišel z jiného světa, asi proto, aby nám ukradl poklady. "
"Není tak rychlý jako Orel, není tak odolný jako stráže z Paláce, a není "
"tak obrovský jako Mutantní břečtan z Mýtiny; díky své inteligenci a přístupu "
"k magickým schopnostem je však velmi nebezpečný.\n\n"
)
S(
"Actually, their powers appear god-like...\n\n",
"Vlastně se zdá, že má až božskou moc...\n\n"
)
S(
"Rogues will never make moves which result in their immediate death. "
"Even when cornered, they are able to instantly teleport back to their "
"home world at any moment, taking the treasures forever... but "
"at least they will not steal anything further!\n\n",
"Chytráci nikdy neudělají tah, který by vedl k jejich okamžité smrti. I když "
"jsou zahnaní do kouta, dokážou se kdykoli okamžitě teleportovat do svého "
"domovského světa a navěky s sebou odnést poklady... ale aspoň už nebudou "
"krást nic dalšího!\n\n")
S(
"Despite this intelligence, Rogues appear extremely surprised "
"by the most basic facts about geometry. They must come from "
"some really strange world.\n\n",
"Navzdory jejich inteligenci se zdá, že Chytráky dokážou nesmírně překvapit "
"i ta nejzákladnější geometrická fakta. Musejí pocházet z nějakého opravdu"
"podivného světa.")
S("change the alpha parameter to show the lines",
"čáry můžeš zviditelnit změnou parametru alfa")
S("triangle grid: not rings", "trojúhelníková mřížka: bez prstenců")
S("triangle grid: rings", "trojúhelníková mřížka: s prstenci")
S("heptagonal grid", "sedmiúhelníková mřížka")
S("rhombic tesselation", "kosočtvercové dělení")
S("triheptagonal tesselation", "troj-sedmiúhelníkové dělení")
S("normal tesselation", "normální dělení")
S("big triangular grid", "velká trojúhelníková mřížka")
S("underlying tree", "stromová základní struktura")
S("circle/horocycle tree", "kruhový/horocyklický strom")
S("zebra triangles", "zebra: trojúhelníky")
S("zebra lines", "zebra: čáry")
S("vineyard pattern", "vinicový vzor")
S("firewall lines", "čáry ohnivých stěn")
S("firewall lines: Palace", "čáry ohnivých stěn: Palác")
S("firewall lines: Power", "čáry ohnivých stěn: Moc")
S("(ESC) tour menu", "(ESC) menu prohlídky")
S("Try the Tutorial to help with understanding the "
"geometry of HyperRogue (menu -> special modes).\n\n",
"Zkuste Tutoriál, chcete-li pomoci s chápáním geometrie "
"HyperRogue (menu -> speciální módy.\n\n")
S("Tutorial", "Tutoriál")
S("spherical geometry", "sférická geometrie")
S("Euclidean geometry", "eukleidovská geometrie")
S("more curved hyperbolic geometry", "zakřivenější hyperbolická geometrie")
S("teleport away", "teleportuj se pryč")
S("Shift-click a location to teleport there.", "Shift-klikni na políčko, kam se chceš teleportovat.")
S("Click a location to teleport there.", "Klikni na políčko, kam se chceš teleportovat.")
S("move through walls", "procházení zdmi")
S("flash", "záblesk")
S("static mode", "statický mód")
S("Static mode enabled.", "Statický mód zapnut.")
S("Static mode disabled.", "Statický mód vypnut.")
S("enable/disable texts", "zapnout/vypnout texty")
S("Help texts disabled.", "Texty nápovědy vypnuty.")
S("next slide", "další snímek")
S("previous slide", "předešlý snímek")
S("This tutorial is different than most other game tutorials -- "
"you are not forced to do anything, and you can go wherever you want.\n\n"
"However, %the1 is not what we are talking about now. "
"We will not explain this land at the moment, and you could ponentially "
"get lost there.\n\n"
"Remember that you can get to the next slide by pressing Enter.",
"Tento tutoriál funguje jinak, než ve většině her -- k ničemu tě nenutíme "
"a můžeš si jít, kam chceš.\n\n"
"Ale %1 není to, o čem teď mluvíme. Tento kraj momentálně tutoriál nevysvětluje "
"a je možné, že se v něm ztratíš.\n\n"
"Nezapomeň, že stiskem klávesy Enter můžeš přejít na další snímek.")
S("Introduction", "Úvod")
S("Welcome to the HyperRogue tutorial!", "Vítej v tutoriálu HyperRogue!")
S(
"This tutorial is mostly aimed to show what is "
"special about the geometry used by HyperRogue. "
"It also shows the basics of gameplay, and "
"how is it affected by geometry.\n\n"
"You decide when you want to stop playing with the "
"current \"slide\" and go to the next one, by pressing Enter. You can also "
"press ESC to see a "
"menu with other options.",
"Tento tutoriál je převážně zaměřen na to, aby ukázal, co je zvláštního "
"na geometrii, kterou HyperRogue používá. Také ukazuje základy hry a to, "
"jak ji geometrie ovlivňuje.\n\n"
"Když si budeš chtít přestat hrát se současným \"snímkem\" a přejít na další, "
"stiskni Enter. Stiskem ESC můžeš také zobrazit menu s dalšími možnostmi.")
S("Basics of gameplay", "Základy hry")
S("gain Ice Diamonds", "získej Ledové diamanty")
S("The game starts in the Icy Lands. Collect the Ice Diamonds "
"(press F1 if you do not know how to move). "
"After you collect many of them, monsters will start to pose a challenge.\n"
"As is typical in roguelikes and other games based on tactical skill rather "
"than story, if you lose, you have to start a new one from the start. "
"However, in this tutorial, you can simply press '4' "
"to teleport away from a bad situation."
"In general, the tutorial is rigged to show you what it "
"wants -- for example, in this slide, you can press '5' to get "
"lots of Ice Diamonds quickly.",
"Hra začíná v Ledovém kraji. Sbírej Ledové diamanty (pokud nevíš, jak "
"se pohybovat, stiskni F1). Když jich nasbíráš mnoho, netvoři začnou "
"být nebezpeční.\n"
"Jak je zvykem ve hrách žánru roguelike a v jiných, které jsou založené "
"na taktických dovednostech a nikoli na příběhu, pokud prohraješ, budeš "
"muset začít hrát od začátku. V tomto tutoriálu se ale můžeš z ošklivé "
"situace jednoduše teleportovat stisknutím klávesy '4'. Tutoriál je "
"obecně dělaný tak, aby ti mohl snadno ukázat, co chce -- v tomto snímku "
"můžeš například stisknout klávesu '5', abys rychle získal velké množství "
"Ledových diamantů.")
S("Hypersian Rug model", "Model hyperského koberce")
S(
"New players think that the action of HyperRogue takes place on a sphere. "
#ifdef MOBWEB
"This is not true -- try the Tutorial in the native desktop version shows "
"the surface HyperRogue actually takes place on.",
#else
"This is not true -- the next slide will show the surface HyperRogue "
"actually takes place on.\n\n"
"Use arrow keys to rotate the model, and Page Up/Down to zoom.\n\n"
"If you do not see anything, press '5' to try a safer renderer.",
#endif
"Noví hráči si často myslí, že se HyperRogue odehrává na povrchu koule. "
#ifdef MOBWEB
"Není to pravda -- Tutoriál v desktopové verzi ti může ukázat povrch, "
"na jakém se HyperRogue opravdu odehrává."
#else
"Není to pravda -- další snímek ti ukáže povrch, na jakém se "
"HyperRogue opravdu odehrává.\n\n"
"Model můžeš otáčet šipkami a zoomovat klávesami Page Up/Down.\n\n"
"Pokud nic nevidíš, stiskni klávesu '5' pro aktivaci bezpečnějšího rendereru."
#endif
)
S("Expansion", "Expanze")
S(
"The next slide shows the number of cells in distance 1, 2, 3, ... from you. "
"It grows exponentially: there are more than 10^100 cells "
"in radius 1000 around you, and you will move further away during the game!\n\n"
"This is extremely important in the design of HyperRogue. "
"HyperRogue has many navigational puzzles -- what would be simple in Euclidean world "
"is extremely tricky "
"in hyperbolic geometry (you want to reach a specific location 20 cells away, "
"which of the thousands of possible directions should you take?); however, other things virtually impossible in Euclidean "
"world become easy in HyperRogue. "
"HyperRogue had to be specially designed so that it is impossible to grind the "
"infinite world. There are almost no permanent upgrades; collecting treasures "
"brings you benefits, but trying to get too many of the same kind is extremely dangerous.",
"Další snímek ukazuje počet políček ve vzdálenosti 1, 2, 3, ... od tebe. "
"Roste exponenciálně: v kruhu o poloměru 1000 kolem tebe je více než 10^100 "
"políček, a během hry dojdeš ještě dál!\n\n"
"Tento fakt je pro design HyperRogue velmi důležitý. Hra obsahuje mnoho "
"navigačních hádanek -- to, co by v eukleidovském světě bylo jednoduché, "
"je v hyperbolické geometrii extrémně složité (chceš se dostat na určité "
"místo 20 políček daleko -- kterým z tisíců možných směrů se máš vydat?); "
"na druhou stranu, jiné věci, které jsou v eukleidovském světě prakticky "
"nemožné, jsou v HyperRogue snadné. HyperRogue musel být speciálně navržen "
"tak, aby se v jeho nekonečném světě nedalo grindovat. Nejsou v něm téměř "
"žádné trvalé upgrady; sbírání pokladů ti přináší výhody, ale pokud se "
"pokusíš získat příliš mnoho pokladů jednoho druhu, bude to nesmírně nebezpečné.")
S("Tiling and Tactics", "Hyperbolické dělení a taktika")
S(
"The tactics of fighting simple monsters, such as the Yetis from the Icy Lands, "
"might appear shallow, but hyperbolic geometry is essential even there. "
"In the next slide, you are attacked by two monsters at once. "
"You can make them line up simply by "
"running away in a straight line. "
"Press '2' to try the same in the Euclidean world -- it is impossible.",
"Taktika boje proti jednoduchým netvorům, jako jsou například Yetiové "
"z Ledového kraje, může vypadat jednoduše, ale i tam je hyperbolická "
"geometrie zásadní. Na dalším snímku na tebe útočí dva netvoři najednou. "
"Pokud budeš utíkat po přímce, přinutíš je, aby se seřadili. Stiskni "
"klávesu '2', abys to samé zkusil v eukleidovském světě -- je to nemožné.")
S("Straight Lines", "Přímky")
S("Hyperbolic geometry has been discovered by the 19th century mathematicians who "
"wondered about the nature of paralellness. Take a line L and a point A. "
"Can a world exist where there is more than one line passing through A "
"which does not cross L?\n\n"
"The Icy Land will be very dangerous if you have lots of Ice Diamonds -- "
"lots of Yetis and Ice Wolves hunting you! But the other lands, where "
"you have no treasures yet, will still be (relatively) safe.\n\n"
"Wander further, and you should find Crossroads quickly -- "
"the Great Walls are straight lines, and indeed, they work differently than in "
"Euclidean. On the other side of Great Walls, you see other lands -- "
"there are about 50 lands in HyperRogue, based "
"on different mechanics and aspects of hyperbolic geometry.",
"Hyperbolickou geometrii objevili matematikové z 19. století, kteří "
"přemýšleli o povaze rovnoběžnosti. Máš-li přímku p a bod A, může "
"existovat svět, ve kterém bodem A prochází více než jedna přímka, "
"která neprotíná p?\n\n"
"Ledový kraj bude velmi nebezpečný, pokud máte hodně Ledových "
"diamantů -- potom tě bude honit spousta Yetiů a Ledových vlků! "
"Ale ostatní kraje, ve kterých ještě žádné poklady nemáš, budou "
"stále bezpečné (relativně).\n\n"
"Půjdeš-li dál, měl bys rychle narazit na Křižovatku -- Velké zdi "
"jsou přímky a skutečně fungují jinak než v eukleidovské geometrii. "
"Na druhé straně Velkých zdí uvidíš jiné kraje -- HyperRogue obsahuje "
"zhruba 50 krajů založených na různých mechanikách a aspektech "
"hyperbolické geometrie.")
S("Running Dogs", "Běžící psi")
S(
"To learn more about straight lines, "
"wander further, and you should find the Land of Eternal Motion. "
"Try to run in a straight line, with a Running Dog next to you. "
"Even though the Running Dog runs at the same speed as you, "
"it will appear to go slower -- this is because you are running "
"in a straight line, and the Running Dog has to run in a curve "
"called an equidistant.\n\n"
#ifdef MAC
"Remember that you can click with right Shift on anything to get more information.",
#else
"Remember that you can right click on anything to get more information.",
#endif
"Chceš-li se dozvědět víc o přímkách, běž dál a měl bys najít Zemi "
"věčného pohybu. Pokus se tam běžet po přímce, zatímco vedle tebe běží "
"Běžící pes. I když běží stejně rychle jako ty, bude se zdát, že je "
"pomalejší -- to proto, že ty běžíš po přímce, zatímco Běžící pes musí "
"běžet po křivce zvané 'ekvidistanta'.\n\n")
#ifdef MAC
"Nezapomeň, že pokud na cokoli klikneš s pravým shiftem, můžeš o tom "
"získat víc informací.",
#else
"Nezapomeň, že pokud na cokoli klikneš pravým tlačítkem, můžeš o tom "
"získat víc informací.",
#endif
S("Equidistants", "Ekvidistanty")
S(
"Equidistants are curves which are at some fixed distance from a "
"straight line. Some lands in HyperRogue are based on equidistants; "
"you should see them after wandering a bit more.\n\n"
"This tutorial gives you freedom to go wherever you choose, "
"but we do not recommend going deep into the Dungeon or the Ocean -- "
"getting back might be difficult.",
"Ekvidistanty jsou křivky, které mají určitou danou vzdálenost od nějaké "
"přímky. V HyperRogue jsou kraje, které jsou na ekvidistantách založeny; "
"když budeš putovat dál, měl bys na ně narazit.\n\n"
"V tomto tutoriálu se můžeš vydat, kam se ti zlíbí, ale doporučujeme, abys "
"nechodil příliš hluboko do Žaláře nebo do Oceánu -- mohl bys mít problém "
"vrátit se zpátky.")
S("Circles", "Kružnice")
S(
"Circles are strange in hyperbolic geometry too. "
"Look for the Castle of Camelot in the Crossroads; "
"the Round Table inside is a circle of radius 28. "
"Finding its center is a difficult challenge.\n\n"
"Press '5' to cheat by seeing the smaller circles too.\n\n"
"Note: Camelot and some other lands are unlocked earlier in the Tutorial than in a real game.",
"I kružnice jsou v hyperbolické geometrii podivné. Zkus na Křižovatce najít "
"hrad Kamelot; Kulatý stůl uvnitř je kružnice o poloměru 28. Najít její střed "
"je obtížný úkol.\n\n"
"Stiskem klávesy '5' můžeš podvádět a vidět i menší kružnice.\n\n"
"Poznámka: Camelot a některé další kraje se v Tutoriálu odemykají "
"dříve než ve skutečné hře.")
S("Horocycles", "Horocykly")
S("Horocycles are similar to circles, but you cannot reach their center at all -- "
"they can be understood as limit circles of infinite radius centered in some point "
"in infinity (also called an ideal point).\n\n"
"Go to R'Lyeh, and you should quickly find a Temple of Cthulhu there. "
"Each circle of columns is actually a horocycle. Horocycles in a given "
"temple are concentric, and there is an infinite number of them.",
"Horocykly se podobají kružnicím, ale jejich středu vůbec nelze dosáhnout "
"-- můžeš si je představit jako limitní kružnice s nekonečným poloměrem, "
"jejichž střed je v nějakém bodě v nekonečnu (takzvaném ideálním bodě).\n\n"
"Běž do R'Lyeh. Měl bys tam rychle najít Cthulhuův chrám. Každý kruh ze "
"sloupů je ve skutečnosti horocyklus. Horocykly v každém chrámu jsou "
"soustředné a je jich nekonečně mnoho.")
S("Half-plane model", "Polorovinový model")
S("The game is normally displayed in the so called Poincaré disk model, "
"which is a kind of a map of the infinite hyperbolic world. "
"There are many projections of Earth, but since Earth is curved, "
"all of them have to distort distances or angles in some way -- "
"the same is true in hyperbolic geometry. "
"The next slide shows another model, called the Poincaré upper half-plane model. In this model, "
"horocycles centered at one specific ideal point are drawn as straight lines.",
"Hra se normálně zobrazuje v modelu nazývaném 'Poincarého disk', což je něco "
"jako mapa nekonečného hyperbolického světa. Země má také mnoho projekcí, "
"ale protože je zakřivená, musejí tyto projekce vždy nějakým způsobem "
"zkreslovat vzdálenosti nebo úhly -- a v hyperbolické geometrii platí totéž. "
"Další snímek ti ukáže jiný model, zvaný 'Poincarého model horní poloroviny'. "
"V tomto modelu vypadají horocykly se středem v jednom specifickém ideálním "
"bodě jako přímky.")
S("Curvature", "Zakřivení")
S("gain Orb of the Sword", "získej Sféru meče")
S(
"Now, go to the Burial Grounds and find an Orb of the Sword. The Sword appears to "
"always be facing in the same direction whatever you do, and it appears that "
"you have to rotate the sword to excavate the treasures; "
"yet, it is possible to excavate them! You migth have already noticed "
"that the world rotates after you move around a loop and return to an old "
"place.\n\n"
"This is related to the fact that the world of HyperRogue is curved, and "
"the sum of angles in a triangle is not equal to 180 degrees.",
"Teď se vydej na Pohřebiště a najdi Sféru meče. Ať děláš, co děláš, Meč bude "
"vždy otočený stejným směrem, a přitom se zdá, že abys mohl vykopat poklady, "
"musíš Meč natočit; přesto je však možné je vykopat! Možná už sis všiml, že "
"když se pohybuješ po uzavřené křivce a vrátíš se tam, odkud jsi vyšel, "
"bude svět pootočený.\n\n"
"To souvisí s faktem, že svět HyperRogue je zakřivený a součet úhlů v trojúhelníku se nerovná 180 stupňům.")
S("Periodic patterns", "Periodické vzory")
S("Hyperbolic geometry yields much more interesting periodic patterns "
"than Euclidean.",
"V hyperbolické geometrii lze najít mnohem zajímavější "
"periodické vzory než v eukleidovské.")
S("Periodic patterns: application", "Periodické vzory: aplikace")
S("Many lands in HyperRogue are based around periodic patterns. "
"For example, both Zebra and Windy Plains are based on the pattern "
"shown in the previous slide. "
"Such lands often have tree-like nature.",
"HyperRogue obsahuje řadu krajů, které jsou založené na periodických "
"vzorech. Tak například Zebra a Větrné pláně jsou obě založené na vzoru "
"na předešlém snímku. Tyto kraje mívají často stromovou povahu.")
S("Fractal landscapes", "Fraktální krajinky")
S("On the following slide, the colors change smoothly in the whole infinite world. "
"Again, this works better than in Euclidean geometry.",
"Na následujícím snímku se barvy v celém nekonečném světě hladce "
"mění. I v tomto případě to v hyperbolické geometrii funguje lépe než "
"v eukleidovské.")
S("Fractal landscapes: application", "Fraktální krajinky: aplikace")
S("create a baby tortoise", "vytvoř želvičku")
S(
"This is applied in HyperRogue to create landscapes, such as the chasms in the "
"land of Reptiles or the Dragon Chasms, which you should find quickly. "
"Also in the Dragon Chasms, you can find a Baby Tortoise, and try to find "
"a matching adult tortoise in the Galápagos. "
"There are over two millions of species, but since there is so much space in "
"hyperbolic geometry, finding a matching tortoise is possible. The brighter "
"the color in Galápagos is, the more aspects of the tortoises in the given "
"area are matching.",
"HyperRogue tohoto využívá pro vytváření krajin, jako jsou propasti v zemi "
"Ještěrek nebo v Dračích propastech, které bys měl rychle najít. V Dračích "
"propastech můžeš také najít Želvičku, a potom se pokusit na Galapágách "
"najít dospělou želvu, která jí odpovídá. Existuje více než dva milióny "
"druhů želv, ale protože v hyperbolické geometrii je tolik místa, je možné "
"najít tu, která patří ke tvé Želvičce. Čím jasnější barva, tím více aspektů "
"želv v dané oblasti odpovídá tvé Želvičce.")
S("Poincaré Ball model", "Model Poincarého koule")
S(
"The Poincaré disk model is a model of a hyperbolic *plane* -- you "
"might wonder why are the walls rendered in 3D then.\n\n"
"HyperRogue actually assumes that the floor level is an equidistant surface "
"in a three-dimensional hyperbolic world, and the camera is placed above the "
"plane that the surface is equidistant to (which boils down to showing "
"the floor level in Poincaré disk model).\n\n"
"This is shown on the next slide, in the Poincaré ball model, which is "
"the 3D analog of the Poincaré disk model.",
"Poincarého disk je model hyperbolické *roviny* -- možná si tedy říkáš, "
"proč se zdi zobrazují ve 3D.\n\n"
"HyperRogue ve skutečnosti předpokládá, že podlaha je ekvidistantní plocha "
"ve trojrozměrném hyperbolickém světě, a že kamera se nachází nad rovinou, "
"ke které je tato plocha ekvidistantní (což ve výsledku znamená, že se "
"podlaha zobrazuje jako Poincarého disk).\n\n"
"To můžeš vidět v následujícím snímku, který ukazuje Poincarého kouli "
"-- 3D analog Poincarého disku.")
S("Hyperboloid model", "Hyperboloidový model")
S(
"Let's see more models of the hyperbolic plane. "
"This model uses a hyperboloid in the Minkowski geometry; "
"it is used internally by HyperRogue.",
"Podívejme se na další modely hyperbolické roviny. Tento model "
"používá hyperboloid v Minkowského geometrii; právě tento model "
"HyperRogue používá interně.")
S("Beltrami-Klein model", "Beltrami-Kleinův model")
S(
"This model renders straight lines as straight, but it distorts angles.",
"Tento model zobrazuje přímky jako přímky, ale zkresluje úhly.")
S("Gans model", "Gansův model")
S(
"Yet another model, which corresponds to orthographic projection of the "
"sphere. Poincaré disk model, Beltrami-Klein model, and the Gans "
"model are all obtained by looking at either the hyperboloid model or an "
"equidistant surface from various distances.",
"A tady máme další model, který odpovídá ortografické projekci koule. Poincerého disk, Beltrami-Kleinův model i Gansův model se získají tak, že se z různých vzdáleností díváte na hyperboloidový model nebo na ekvidistantní plochu.")
S("Band model", "Pásový model")
S("render spiral", "renderování spirály")
S(
"The band model is the hyperbolic analog of the Mercator projection of the sphere: "
"a given straight line is rendered as a straight line, and the rest of the "
"world is mapped conformally, that is, angles are not distorted. "
"Here, we take the straight line connecting your starting point and your "
"current position -- usually the path taken by the player is surprisingly "
"close to a straight line. Press '8' to see this path.\n\n"
"If you want, press '5' to see it rendered as a spiral, although it takes lots of time and "
"memory.",
"Pásový model je hyperbolickým analogem Mercatorovy projekce na kouli: "
"jedna daná přímka se zobrazí jako přímka a zbytek světa je namapován "
"konformálně, tedy bez zkreslení úhlů. V tomto případě použijeme přímku, "
"která spojuje bod, kde jsi začal hru, a tvou současnou polohu -- dráha, "
"po které hráč jde, je obvykle překvapivě blízká přímce. Tuto cestu můžeš "
"vidět stisknutím klávesy '8'.\n\n"
"Pokud chceš, můžeš ji také stisknutím klávesy '5' vyrenderovat jako spirálu; "
"vyžaduje to však hodně času a paměti.")
S("Conformal square model", "Konformální čtvercový model")
S("The world can be mapped conformally to a square too.",
"Svět je také možné konformálně namapovat na čtverec.")
S("Shoot'em up mode", "Mód střílečky")
S("In the shoot'em up mode, space and time is continuous. "
"You attack by throwing knives. "
"Very fun with two players!\n\n"
"There are other special modes too which change the gameplay or "
"focus on a particular challenge.",
"V módu střílečky je prostor i čas spojitý. Útočíš "
"vrháním nožů. Veliká legrace ve dvou hráčích!\n\n"
"HyperRogue také obsahuje další speciální módy, které mění "
"způsob hry nebo jsou zaměřené na určitý úkol.")
S("THE END", "KONEC")
S("leave the Tutorial", "opusť Tutoriál")
S(
"This tour shows just a small part of what you can see in the world of HyperRogue. "
"For example, "
"hyperbolic mazes are much nicer than their Euclidean counterparts. "
"Have fun exploring!\n\n"
"Press '5' to leave the tutorial mode.",
"Tato prohlídka ukazuje jen malou část toho, co můžeš vidět ve světě "
"HyperRogue. Tak například: hyperbolická bludiště jsou mnohem hezčí "
"než jejich eukleidovské protějšky. Bav se při dalším zkoumání!\n\n."
"Stisknutím klávesy '5' opustíš tutoriál."
)
#undef Orb

View File

@ -4940,7 +4940,505 @@ S("field quotient", "przestrzeń ilorazowa ciała")
"NEW_ACHIEVEMENT_8_18_DESC" "Defeat a Sandworm in the Zebra Quotient geometry."
*/
// additional texts for 9.4k
N("Tortoise", GEN_M, "Żółw", "Żółwie", "Żółwia", "Żółwiem")
S("line patterns", "wzory linii")
S("1 turn", "1 kolejka")
S("%1 turns", "kolejek: %1")
S("items/kills mode", "tryb rzeczy/zabić")
S("images", "obrazki")
S("letters", "literki")
S("input", "sterowanie")
S("default", "domyślne")
S("config", "ustawione")
S("expansion", "rozszerzanie")
S("continue", "kontynuuj")
S("main menu", "menu główne")
S("restart", "nowa gra")
S("quit", "koniec")
S("exit menu", "wyjdź z menu")
S(
"A tourist from another world. They mutter something about the 'tutorial', "
"and claim that they are here just to learn, and to leave without any treasures. "
"Do not kill them!",
"Turyst%aka0 z innego świata. Coś mamrocze o 'podręczniku', i że "
"się tylko uczy, że nie jest tu po skarby. Nie zabijać!")
S(
"This monster has come from another world, presumably to steal our treasures. "
"Not as fast as an Eagle, not as resilient as the guards from the Palace, "
"and not as huge as the Mutant Ivy from the Clearing; however, "
"they are very dangerous because of their intelligence, "
"and access to magical powers.\n\n",
"Ten potwór przybył z innego świata, prawdopodobnie po nasze skarby. "
"Nie taki szybki jak Orzeł, nie taki odporny jak strażnicy Pałacu, "
"i nie taki wielki jak Zmutowany Bluszcz z Polany; jest jednak "
"bardzo niebezpieczny ze względu na inteligencję i "
"dostęp do mocy magicznych.\n\n"
)
S(
"Actually, their powers appear god-like...\n\n",
"Jego moce wyglądają właściwie na boskie...\n\n"
)
S(
"Rogues will never make moves which result in their immediate death. "
"Even when cornered, they are able to instantly teleport back to their "
"home world at any moment, taking the treasures forever... but "
"at least they will not steal anything further!\n\n",
"Cwaniacy nigdy nie robią ruchów, po których by zostali od razu zabici. "
"Nawet gdy się ich otoczy, są zdolni natychmiast teleportować się "
"i wrócić do świata, skąd pochodzą, zabierając skarby na zawsze... "
"ale przynajmniej nie ukradną już nic więcej!\n\n")
S(
"Despite this intelligence, Rogues appear extremely surprised "
"by the most basic facts about geometry. They must come from "
"some really strange world.\n\n",
"Mimo ich inteligencji Cwaniacy wyglądają na szalenie zdziwionych "
"nawet najprostszymi faktami geometrycznymi. Muszą pochodzić z jakiegoś "
"bardzo dziwnego świata.")
S("change the alpha parameter to show the lines",
"zmień parametr alfa by linie były widoczne")
S("triangle grid: not rings", "trójkątna siatka: nie pierścienie")
S("triangle grid: rings", "trójkątna siatka: pierścienie")
S("heptagonal grid", "siatka siedmiokątna")
S("rhombic tesselation", "posadzka rombowa")
S("triheptagonal tesselation", "posadzka trójkątno-siedmiokątna")
S("normal tesselation", "zwykła posadzka")
S("big triangular grid", "duża siatka trójkątna")
S("underlying tree", "drzewo bazowe")
S("circle/horocycle tree", "drzewo bazowe dla kół/horocykli")
S("zebra triangles", "zebra: trójkąty")
S("zebra lines", "zebra: linie")
S("vineyard pattern", "wzór winnicy")
S("firewall lines", "linie ścian ognia")
S("firewall lines: Palace", "linie ścian ognia: Pałac")
S("firewall lines: Power", "linie ścian ognia: Moc")
S("(ESC) tour menu", "(ESC) menu ucznia")
S("Try the Tutorial to help with understanding the "
"geometry of HyperRogue (menu -> special modes).\n\n",
"Uruchom Podręcznik, by zrozumieć geometrię HyperRogue (menu -> tryby specjalne.\n\n")
S("Tutorial", "Podręcznik")
S("spherical geometry", "geometria sferyczna")
S("Euclidean geometry", "geometria euklidesowa")
S("more curved hyperbolic geometry", "większa krzywizna")
S("teleport away", "uciekaj stąd (teleport)")
S("Shift-click a location to teleport there.", "Shift-kliknij pole, by tam się teleportować.")
S("Click a location to teleport there.", "Kliknij pole, by tam się teleportować.")
S("move through walls", "przechodź przez ściany")
S("flash", "błysk")
S("static mode", "tryb statyczny")
S("Static mode enabled.", "Tryb statyczny włączony.")
S("Static mode disabled.", "Tryb statyczny wyłączony.")
S("enable/disable texts", "włącz/wyłącz teksty")
S("Help texts disabled.", "Teksty pomocy wyłączone.")
S("next slide", "kolejny slajd")
S("previous slide", "poprzedni slajd")
S("This tutorial is different than most other game tutorials -- "
"you are not forced to do anything, and you can go wherever you want.\n\n"
"However, %the1 is not what we are talking about now. "
"We will not explain this land at the moment, and you could ponentially "
"get lost there.\n\n"
"Remember that you can get to the next slide by pressing Enter.",
"Ten podręcznik jest inny niż większość innych -- "
"nie masz obowiązku robić tego co tutorial chce, możesz iść dokąd chcesz.\n\n"
"Ale %1 nie jest miejscem, o którym teraz mówimy. Nie wyjaśnimy go, "
"i potencjalnie możesz się zgubić.\n\n"
"Naciśnij Enter by przejść do kolejnego slajdu.")
S("Introduction", "Wstęp")
S("Welcome to the HyperRogue tutorial!", "Witaj w podręczniku HyperRogue!")
S(
"This tutorial is mostly aimed to show what is "
"special about the geometry used by HyperRogue. "
"It also shows the basics of gameplay, and "
"how is it affected by geometry.\n\n"
"You decide when you want to stop playing with the "
"current \"slide\" and go to the next one, by pressing Enter. You can also "
"press ESC to see a "
"menu with other options.",
"Zadaniem tego podręcznika jest pokazanie szczególnych własności "
"geometrii używanej przez HyperRogue; są też pokazane podstawy "
"rozgrywki, i jak geometria na nie wpływa.\n\n"
"Ty decydujesz, kiedy chcesz skończyć bawić się obecnym \"slajdem\" "
"i przejść do kolejnego, naciskając Enter. Naciśnij ESC by zobaczyć "
"pozostałe opcje.")
S("Basics of gameplay", "Podstawy rozgrywki")
S("gain Ice Diamonds", "daj Lodowe Diamenty")
S("The game starts in the Icy Lands. Collect the Ice Diamonds "
"(press F1 if you do not know how to move). "
"After you collect many of them, monsters will start to pose a challenge.\n"
"As is typical in roguelikes and other games based on tactical skill rather "
"than story, if you lose, you have to start a new one from the start. "
"However, in this tutorial, you can simply press '4' "
"to teleport away from a bad situation."
"In general, the tutorial is rigged to show you what it "
"wants -- for example, in this slide, you can press '5' to get "
"lots of Ice Diamonds quickly.",
"Gra rozpoczyna się w Lodowej Krainie. Zbieraj Lodowe Diamenty "
"(naciśnij F1 jeśli nie wiesz jak się ruszać). "
"Po zebraniu wielu Diamentów ataki potworów staną się "
"wyzwaniem. Zgodnie z konwencjami gier roguelike, "
"jeśli przegrasz, zaczynasz od początku; "
"w tym podręczniku jednak wystarczy nacisnąć '4', "
"by uciec ze złej sytuacji. Podręcznik jest "
"podkręcony tak, by pokazać to co chce -- "
"na przykład tutaj możesz nacisnąć '5' by "
"zdobyć szybko dużo diamentów.")
S("Hypersian Rug model", "Model Hiperskiego Dywanu")
S(
"New players think that the action of HyperRogue takes place on a sphere. "
#ifdef MOBWEB
"This is not true -- the Tutorial in the native desktop version shows "
"the surface HyperRogue actually takes place on.",
#else
"This is not true -- the next slide will show the surface HyperRogue "
"actually takes place on.\n\n"
"Use arrow keys to rotate the model, and Page Up/Down to zoom.\n\n"
"If you do not see anything, press '5' to try a safer renderer.",
#endif
"Nowi gracze myślą, że akcja HyperRogue toczy się na sferze. "
#ifdef MOBWEB
"To nieprawda -- Podręcznik w komputerowej wersji wykonywalnej "
"pokazuje powierzchnię, na której w rzeczywistości toczy się rozgrywka."
#else
"To nieprawda -- kolejny slajd pokazuje powierzchnię, "
"na której toczy się gra. "
"Obracaj modelem strzałkami, Page Up/Down by skalować.\n\n"
"Jeśli nic nie widzisz, naciśnij '5' dla bezpieczniejszego renderera."
#endif
)
S("Expansion", "Ekspansja")
S(
"The next slide shows the number of cells in distance 1, 2, 3, ... from you. "
"It grows exponentially: there are more than 10^100 cells "
"in radius 1000 around you, and you will move further away during the game!\n\n"
"This is extremely important in the design of HyperRogue. "
"HyperRogue has many navigational puzzles -- what would be simple in Euclidean world "
"is extremely tricky "
"in hyperbolic geometry (you want to reach a specific location 20 cells away, "
"which of the thousands of possible directions should you take?); however, other things virtually impossible in Euclidean "
"world become easy in HyperRogue. "
"HyperRogue had to be specially designed so that it is impossible to grind the "
"infinite world. There are almost no permanent upgrades; collecting treasures "
"brings you benefits, but trying to get too many of the same kind is extremely dangerous.",
"Kolejny slajd pokazuje liczbę pól w odległości 1, 2, 3, ... od Ciebie. "
"Rośnie ona wykładniczo: jest ponad 10^100 pól w promieniu 1000 od Ciebie, "
"i w trakcie gry będziesz odchodzić dalej!\n\n"
"Jest to bardzo ważne dla designu HyperRogue. Są tu zagadki nawigacyjne -- "
"coś co by było proste w świecie euklidesowej wymaga przemyślenia "
"w geometrii hiperbolicznej (chcesz dostać się do miejsca 20 pól od Ciebie, "
"który z tysiąca możliwych kierunków wybrać?); z kolei inne rzeczy stają się "
"tu łatwe. Gra HyperRogue jest zaprojektowana tak, by nie dało się "
"'grindować' nieskończonego świata -- prawie nie ma permanentnych ulepszeń, "
"zbieranie skarbów przynosi pożytki, ale zdobycie wielu jednego rodzaju "
"jest skrajnie niebezpieczne.")
S("Tiling and Tactics", "Posadzka i taktyka")
S(
"The tactics of fighting simple monsters, such as the Yetis from the Icy Lands, "
"might appear shallow, but hyperbolic geometry is essential even there. "
"In the next slide, you are attacked by two monsters at once. "
"You can make them line up simply by "
"running away in a straight line. "
"Press '2' to try the same in the Euclidean world -- it is impossible.",
"Taktyka walki z prostymi potworami, jak Yeti z Krainy Lodu, może się "
"wydawać płytka, ale geometria hiperboliczna jest istotna nawet tu. "
"W następnym slajdzie atakują Cię 2 potwory naraz. Możesz uciec po prostu "
"odchodząc od nich w linii prostej. Naciśnij '2', by spróbować tego "
"w świecie euklidesowym -- jest to niemożliwe.")
S("Straight Lines", "Linie proste")
S("Hyperbolic geometry has been discovered by the 19th century mathematicians who "
"wondered about the nature of paralellness. Take a line L and a point A. "
"Can a world exist where there is more than one line passing through A "
"which does not cross L?\n\n"
"The Icy Land will be very dangerous if you have lots of Ice Diamonds -- "
"lots of Yetis and Ice Wolves hunting you! But the other lands, where "
"you have no treasures yet, will still be (relatively) safe.\n\n"
"Wander further, and you should find Crossroads quickly -- "
"the Great Walls are straight lines, and indeed, they work differently than in "
"Euclidean. On the other side of Great Walls, you see other lands -- "
"there are about 50 lands in HyperRogue, based "
"on different mechanics and aspects of hyperbolic geometry.",
"Geometria hiperboliczna została odkryta przez dziewiętnastowiecznych matematyków "
"zainteresowanych naturą równoległości. Weź linię prostą L i punkt A. Czy może "
"istnieć świat, w którym jest więcej niż jedna linia prosta przechodząca przez A, "
"ale nie przecinająca L?\n\n"
"Kraina Lodu jest bardzo niebezpieczna, gdy masz mnóstwo Diamentów. "
"Ale inne krainy, w których jeszcze nie masz skarbów, są w miarę bezpieczne.\n\n"
"Zwiedzaj dalej, a szybko znajdziesz Skrzyżowanie -- jego ściany są "
"liniami prostymi, i działają inaczej niż w geometrii euklidesowej. "
"Po drugiej stronie Wielkich Ścian widzisz inne krainy -- jest ich około 50, "
"opartych na róznych aspektach geometrii hiperbolicznej.")
S("Running Dogs", "Biegnące Psy")
S(
"To learn more about straight lines, "
"wander further, and you should find the Land of Eternal Motion. "
"Try to run in a straight line, with a Running Dog next to you. "
"Even though the Running Dog runs at the same speed as you, "
"it will appear to go slower -- this is because you are running "
"in a straight line, and the Running Dog has to run in a curve "
"called an equidistant.\n\n"
#ifdef MAC
"Remember that you can click with right Shift on anything to get more information.",
#else
"Remember that you can right click on anything to get more information.",
#endif
"By dowiedzieć się więcej o liniach prostych, "
"podróżuj dalej, aż znajdziesz Krainę Wiecznego Ruchu. "
"Biegnij w linii prostej z Psem biegnącym obok. "
"Mimo że Pies biegnie z tą samą prędkością, nie będzie "
"w stanie Cię dogonić -- ponieważ Ty ruszasz się w linii prostej, "
"a Pies biegnie po krzywej zwanej ekwidystantą.\n\n"
#ifdef MAC
"Pamiętaj, że możesz klikać z prawym Shiftem na różnych elementach gry, by dowiedzieć się o nich więcej."
#else
"Pamiętaj, że możesz klikać prawym przyciskiem na różnych elementach gry, by dowiedzieć się o nich więcej."
#endif
)
S("Equidistants", "Ekwidystanty")
S(
"Equidistants are curves which are at some fixed distance from a "
"straight line. Some lands in HyperRogue are based on equidistants; "
"you should see them after wandering a bit more.\n\n"
"This tutorial gives you freedom to go wherever you choose, "
"but we do not recommend going deep into the Dungeon or the Ocean -- "
"getting back might be difficult.",
"Ekwidystanty to krzywe w stałej odległości od linii prostej. "
"Niektóre krainy w grze są oparte na ekwidystantach; "
"po krótkiej podróży je zobaczysz.\n\n"
"Ten podręcznik pozwala Ci się ruszać dokąd chcesz, "
"ale nie polecamy zagłębiać się w Lochy ani w Ocean -- "
"powrót może być trudny.")
S("Circles", "Koła")
S(
"Circles are strange in hyperbolic geometry too. "
"Look for the Castle of Camelot in the Crossroads; "
"the Round Table inside is a circle of radius 28. "
"Finding its center is a difficult challenge.\n\n"
"Press '5' to cheat by seeing the smaller circles too.\n\n"
"Note: Camelot and some other lands are unlocked earlier in the Tutorial than in a real game.",
"Koła również są dziwne w geometrii hiperbolicznej. "
"Szukaj zamku Camelot na Skrzyżowaniu; Okrągły Stół "
"jest kołem o promieniu 28. Znalezienie jego środka "
"to trudne wyzwanie.\n\n"
"Naciśnij '5' by oszukać -- zobaczyć mniejsze okręgi.\n\n"
"Uwaga: Camelot i niektóre inne krainy w tym podręczniku są pokazywane wcześniej "
"niż w normalnej grze.")
S("Horocycles", "Horocykle")
S("Horocycles are similar to circles, but you cannot reach their center at all -- "
"they can be understood as limit circles of infinite radius centered in some point "
"in infinity (also called an ideal point).\n\n"
"Go to R'Lyeh, and you should quickly find a Temple of Cthulhu there. "
"Each circle of columns is actually a horocycle. Horocycles in a given "
"temple are concentric, and there is an infinite number of them.",
"Horocykle są podobne do okręgów, ale nie możesz dotrzeć do ich środka -- "
"są to graniczne okręgi o nieskończonym promieniu, których środek jest w nieskończoności "
"(takie punkty nazywamy punktami idealnymi).\n\n"
"Idź do R'Lyeh, i szybko znajdziesz Świątynię Cthulhu. Każdy krąg kolumn "
"jest horocyklem. Horocykle w danej świątyni są współśrodkowe, i jest ich "
"nieskończenie wiele.")
S("Half-plane model", "Model półpłaszczyzny")
S("The game is normally displayed in the so called Poincaré disk model, "
"which is a kind of a map of the infinite hyperbolic world. "
"There are many projections of Earth, but since Earth is curved, "
"all of them have to distort distances or angles in some way -- "
"the same is true in hyperbolic geometry. "
"The next slide shows another model, called the Poincaré upper half-plane model. In this model, "
"horocycles centered at one specific ideal point are drawn as straight lines.",
"Gra jest normalnie w tak zwanym modelu Poincaré, rodzaju mapy nieskończonego "
"hiperbolicznego świata. Istnieje wiele rodzajów rzutu Ziemi, ale "
"ze względu na jej krzywiznę, każdy z nich przekłamuje odległości czy kąty "
"w jakiś sposób -- to samo dzieje się w geometrii hiperbolicznej. "
"Następny slajd pokazuje inny model, model półpłaszczyzny. "
"W tym modelu horocykle o środku w danym punkcie idealnym wyglądają jak linie "
"poziome.")
S("Curvature", "Krzywizna")
S("gain Orb of the Sword", "zdobądź Sferę Ostrza")
S(
"Now, go to the Burial Grounds and find an Orb of the Sword. The Sword appears to "
"always be facing in the same direction whatever you do, and it appears that "
"you have to rotate the sword to excavate the treasures; "
"yet, it is possible to excavate them! You migth have already noticed "
"that the world rotates after you move around a loop and return to an old "
"place.\n\n"
"This is related to the fact that the world of HyperRogue is curved, and "
"the sum of angles in a triangle is not equal to 180 degrees.",
"Teraz idź do Kurhanów i znajdź Sferę Ostrza. Ostrze wygląda jakby zawsze było "
"skierowane w tą samą stronę, a wydaje się, że do wykopania skarbów trzeba "
"je obrócić. Jednak wykopanie skarbów jest możliwe! Być może już zauważy%łeś0, "
"że świat się obraca, gdy zrobisz pętlę.\n\n"
"Jest to związane z zakrzywieniem świata HyperRogue, i tym, że suma kątów "
"trójkąta nie jest równa 180 stopni.")
S("Periodic patterns", "Wzory okresowe")
S("Hyperbolic geometry yields much more interesting periodic patterns "
"than Euclidean.",
"W geometrii hiperbolicznej są dużo bardziej ciekawe regularne wzory "
"niż w euklidesowej.")
S("Periodic patterns: application", "Zastosowanie wzorów okresowych")
S("Many lands in HyperRogue are based around periodic patterns. "
"For example, both Zebra and Windy Plains are based on the pattern "
"shown in the previous slide. "
"Such lands often have tree-like nature.",
"Wiele krain jest opartych na okresowych wzorach. Na przykład Zebra "
"i Wietrzna Równina są obie oparte na wzorze z poprzedniego slajdu. "
"Krainy takie mają zwykle drzewiastą strukturę.")
S("Fractal landscapes", "Fraktalne krajobrazy")
S("On the following slide, the colors change smoothly in the whole infinite world. "
"Again, this works better than in Euclidean geometry.",
"Na kolejnym slajdzie kolory się płynnie zmieniają w nieskończonym świecie. "
"To również działa lepiej niż w geometrii euklidesowej.")
S("Fractal landscapes: application", "Zastosowanie fraktalnych krajobrazów")
S("create a baby tortoise", "stwórz żółwika")
S(
"This is applied in HyperRogue to create landscapes, such as the chasms in the "
"land of Reptiles or the Dragon Chasms, which you should find quickly. "
"Also in the Dragon Chasms, you can find a Baby Tortoise, and try to find "
"a matching adult tortoise in the Galápagos. "
"There are over two millions of species, but since there is so much space in "
"hyperbolic geometry, finding a matching tortoise is possible. The brighter "
"the color in Galápagos is, the more aspects of the tortoises in the given "
"area are matching.",
"Jest to używane w grze do stworzenia krajobrazów, jak przepaści w "
"Jaszczurkach lub Smoczych Otchłaniach, które niedł↓go znajdziesz. "
"W Smoczych Otchłaniach możesz znaleźć Żółwika, i poszukać "
"pasującego dorosłego żółwia w Galápagos. Jest ponad 2 miliony gatunków, "
"ale ze względu na ilość miejsca w geometrii hiperbolicznej, znalezienie "
"pasującego żółwia jest możliwe. Im jaśniejszy kolor w Galápagos, tym "
"więcej aspektów żółwika pasuje do żółwii z danego terenu.")
S("Poincaré Ball model", "Model kuli")
S(
"The Poincaré disk model is a model of a hyperbolic *plane* -- you "
"might wonder why are the walls rendered in 3D then.\n\n"
"HyperRogue actually assumes that the floor level is an equidistant surface "
"in a three-dimensional hyperbolic world, and the camera is placed above the "
"plane that the surface is equidistant to (which boils down to showing "
"the floor level in Poincaré disk model).\n\n"
"This is shown on the next slide, in the Poincaré ball model, which is "
"the 3D analog of the Poincaré disk model.",
"Model dysku Poincaré to model *płaszczyny* hiperbolicznej -- "
"być może się zastanawiasz, jak w takim razie rozumieć ściany w 3D.\n\n"
"HyperRogue zakłada, że powierzchnia podłogi to powierzchnia ekswidystantna "
"w trójwymiarowym hiperbolicznym świecie, a kamera znajduje się nad powierzchnią, "
"do której podłoga jest ekwidystantna -- co powoduje, że podłoga wygląda "
"dokładnie jak w modelu Poincaré.\n\n"
"Pokazuje to kolejny slajd, w modelu kuli, trójwymiarowym odpowiedniku modelu dysku.")
S("Hyperboloid model", "Model hiperboloidy")
S(
"Let's see more models of the hyperbolic plane. "
"This model uses a hyperboloid in the Minkowski geometry; "
"it is used internally by HyperRogue.",
"Pokażemy teraz więcej modeli. To jest hiperboloida w geometrii Minkowskiego; "
"HyperRogue wewnętrznie używa tego modelu.")
S("Beltrami-Klein model", "Model Beltramiego-Kleina")
S(
"This model renders straight lines as straight, but it distorts angles.",
"Ten model pokazuje linie proste jako proste, ale przekłamuje kąty.")
S("Gans model", "Model Gansa")
S(
"Yet another model, which corresponds to orthographic projection of the "
"sphere. Poincaré disk model, Beltrami-Klein model, and the Gans "
"model are all obtained by looking at either the hyperboloid model or an "
"equidistant surface from various distances.",
"Kolejny model, odpowiadający ortograficznemu rzutowi sfery. Model dysku, "
"Kleina i Gansa powstają przez patrzenie na model hiperboloidy lub "
"powierzchnię ekwidystantną z różnych odległości.")
S("Band model", "Model wstęgi")
S("render spiral", "rysuj spiralę")
S(
"The band model is the hyperbolic analog of the Mercator projection of the sphere: "
"a given straight line is rendered as a straight line, and the rest of the "
"world is mapped conformally, that is, angles are not distorted. "
"Here, we take the straight line connecting your starting point and your "
"current position -- usually the path taken by the player is surprisingly "
"close to a straight line. Press '8' to see this path.\n\n"
"If you want, press '5' to see it rendered as a spiral, although it takes lots of time and "
"memory.",
"Model wstęgi to hiperboliczny analog rzutu Mercatora: "
"pewna linia prosta jest rysowana jaka linia prosta, a reszta świata jest "
"odwzorowana konforemnie, tzn. kąty nie są przekłamywane. "
"Tutaj jako centralną linię prostą bierzemy linię łączącą punkt początkowy i "
"Twoją obecną pozycję -- zazwyczaj droga wybrana przez gracza jest "
"niespodzianie zbliżona do linii prostej. Naciśnij '8', by zobaczyć ścieżkę.\n\n"
"Możesz też nacisnąć '5' by zobaczyć to w postaci spirali, ale wymaga to "
"bardzo dużo czasu i pamięci.")
S("Conformal square model", "Konforemny kwadrat")
S("The world can be mapped conformally to a square too.",
"Świat można też konforemnie odwzorować na kwadrat.")
S("Shoot'em up mode", "Tryb strzelanki")
S("In the shoot'em up mode, space and time is continuous. "
"You attack by throwing knives. "
"Very fun with two players!\n\n"
"There are other special modes too which change the gameplay or "
"focus on a particular challenge.",
"W trybie strzelanki czas i przestrzeń są ciągłe. Atakujesz "
"rzucając nożami. Bardzo fajne na dwóch graczy!\n\n"
"Jest wiele trybów specjalnych, zmieniających rozgrywkę lub "
"koncentrujących się na konkretnym wyzwaniu.")
S("THE END", "KONIEC")
S("leave the Tutorial", "opuść Podręcznik")
S(
"This tour shows just a small part of what you can see in the world of HyperRogue. "
"For example, "
"hyperbolic mazes are much nicer than their Euclidean counterparts. "
"Have fun exploring!\n\n"
"Press '5' to leave the tutorial mode.",
"Ten podręcznik pokazuje tylko małą część świata HyperRogue. Na przykład "
"hiperboliczne labirynty są ciekawsze niż euklidesowe. Miłej zabawy!"
"Naciśnij '5' by opuścić podręcznik."
)
#undef Orb

View File

@ -5087,5 +5087,496 @@ S("A land for people wanting to experiment with cellular automata in the HyperRo
"NEW_ACHIEVEMENT_8_18_DESC" "Победите Земляного червя в фактор-геометрии зебры."
*/
N("Tortoise", GEN_F, "Черепаха", "Черепахи", "Черепаху", "Черепахой")
S("line patterns", "шаблоны линий")
S("1 turn", "1 ход")
S("%1 turns", "ходов: %1")
S("items/kills mode", "режим предметов/убийств")
S("images", "изображения")
S("letters", "буквы")
S("input", "ввод")
S("default", "по умолчанию")
S("config", "настройки")
S("expansion", "расширение")
S("continue", "продолжить")
S("main menu", "главное меню")
S("restart", "новая игра")
S("quit", "выход")
S("exit menu", "выйти из меню")
S(
"A tourist from another world. They mutter something about the 'tutorial', "
"and claim that they are here just to learn, and to leave without any treasures. "
"Do not kill them!",
"Турист из другого мира. Они бормочут что-то про 'руководство', и "
"говорят, что хотят научить, а не забрать сокровища. Не убивай их!")
S(
"This monster has come from another world, presumably to steal our treasures. "
"Not as fast as an Eagle, not as resilient as the guards from the Palace, "
"and not as huge as the Mutant Ivy from the Clearing; however, "
"they are very dangerous because of their intelligence, "
"and access to magical powers.\n\n",
"Этот монстр прибыл из другого мира, видимо, чтобы украсть наши сокровища. "
"Не такой быстрый, как орёл, не такой живучий, как стражники из Дворца, "
"не такой живучий, как плющ-мутант с Поляны; однако они "
"опасны из-за их интеллекта и доступа к магическим силам.\n\n"
)
S(
"Actually, their powers appear god-like...\n\n",
"Его силы кажутся богоподобными...\n\n"
)
S(
"Rogues will never make moves which result in their immediate death. "
"Even when cornered, they are able to instantly teleport back to their "
"home world at any moment, taking the treasures forever... but "
"at least they will not steal anything further!\n\n",
"Разбойник никогда не сделает ход, ведущий к его смерти. "
"Когда они окружены, они могут мгновенно телепортироваться обратно "
"в их родной мир, забирая все сокровища... но хотя бы "
"не украдут ничего в будущем!\n\n")
S(
"Despite this intelligence, Rogues appear extremely surprised "
"by the most basic facts about geometry. They must come from "
"some really strange world.\n\n",
"Несмотря на их интеллект, Разбойники весьма удивлены "
"простейшими фактами из геометрии. Наверное, они пришли "
"из очень странного мира\n\n.")
S("change the alpha parameter to show the lines",
"измените параметр альфа, чтобы увидеть эти линии")
S("triangle grid: not rings", "треугольная сетка: нет колец")
S("triangle grid: rings", "треугольная сетка: кольца")
S("heptagonal grid", "семиугольная сетка")
S("rhombic tesselation", "замощение ромбами")
S("triheptagonal tesselation", "замощение треугольниками и семиугольниками")
S("normal tesselation", "обычное замощение")
S("big triangular grid", "большая треугольная сетка")
S("underlying tree", "основное дерево")
S("circle/horocycle tree", "основное дерево для окружностей/орициклов")
S("zebra triangles", "зебра: треугольники")
S("zebra lines", "зебра: линии")
S("vineyard pattern", "узор виноградника")
S("firewall lines", "стены огня")
S("firewall lines: Palace", "стены огня: Дворец")
S("firewall lines: Power", "стены огня: Сила")
S("(ESC) tour menu", "(ESC) меню обучения")
S("Try the Tutorial to help with understanding the "
"geometry of HyperRogue (menu -> special modes).\n\n",
"Попробуйте Руководство, чтобы понять геометрию HyperRogue (меню -> специальные режимы.\n\n")
S("Tutorial", "Руководство")
S("spherical geometry", "сферическая геометрия")
S("Euclidean geometry", "евклидова геометрия")
S("more curved hyperbolic geometry", "более искривлённая геометрия")
S("teleport away", "телепортироваться отсюда")
S("Shift-click a location to teleport there.", "Shift-клик на поле, чтобы телепортироваться туда.")
S("Click a location to teleport there.", "Кликни на поле, чтобы телепортироваться туда.")
S("move through walls", "проходить сквозь стены")
S("flash", "вспышка")
S("static mode", "статичный режим")
S("Static mode enabled.", "Статичный режим включен.")
S("Static mode disabled.", "Статичный режим выключен.")
S("enable/disable texts", "включить/выключить тексты")
S("Help texts disabled.", "Тексты помощи выключены.")
S("next slide", "следующий слайд")
S("previous slide", "предыдущий слайд")
S("This tutorial is different than most other game tutorials -- "
"you are not forced to do anything, and you can go wherever you want.\n\n"
"However, %the1 is not what we are talking about now. "
"We will not explain this land at the moment, and you could ponentially "
"get lost there.\n\n"
"Remember that you can get to the next slide by pressing Enter.",
"Это руководство отличается от большинства других -- "
"ты не обязан ничего делать, иди куда хочешь.\n\n"
"Однако %1 -- не то, о чём мы сейчас говорим. Мы не будем сейчас "
"объяснять эту землю, и ты можешь заблудиться в ней.\n\n"
"Нажми Enter, чтобы перейти на следующий слайд.")
S("Introduction", "Введение")
S("Welcome to the HyperRogue tutorial!", "Добро пожаловать в руководство HyperRogue!")
S(
"This tutorial is mostly aimed to show what is "
"special about the geometry used by HyperRogue. "
"It also shows the basics of gameplay, and "
"how is it affected by geometry.\n\n"
"You decide when you want to stop playing with the "
"current \"slide\" and go to the next one, by pressing Enter. You can also "
"press ESC to see a "
"menu with other options.",
"Главная цель этого руководства -- показать особенности геометрии "
"в HyperRogue. Также здесь объясняются основы игры, и как геометрия "
"на них влияет.\n\n"
"Ты можешь перейти на следующий \"слайд\", "
"нажав Enter. Нажми ESC, чтобы открыть меню с другими опциями.")
S("Basics of gameplay", "Начала игры")
S("gain Ice Diamonds", "собери Ледяные алмазы")
S("The game starts in the Icy Lands. Collect the Ice Diamonds "
"(press F1 if you do not know how to move). "
"After you collect many of them, monsters will start to pose a challenge.\n"
"As is typical in roguelikes and other games based on tactical skill rather "
"than story, if you lose, you have to start a new one from the start. "
"However, in this tutorial, you can simply press '4' "
"to teleport away from a bad situation."
"In general, the tutorial is rigged to show you what it "
"wants -- for example, in this slide, you can press '5' to get "
"lots of Ice Diamonds quickly.",
"Игра начинается в Ледяной земле. Собирай Ледяные алмазы "
"(нажми F1, если не знаешь, как ходить). "
"Когда ты соберёшь много алмазов, монстры начнут "
"становиться проблемой. Как и в других играх жанра roguelike, "
"после проигрыша ты начнёшь играть с начала; "
"но в пределах этого руководства ты можешь нажать '4', "
"чтобы телепортироваться из плохой ситуации. Руководство "
"устроено так, чтобы показать тебе игру -- "
"например, на этом слайде ты можешь нажать '5', чтобы "
"получить сразу много алмазов.")
S("Hypersian Rug model", "Модель Гиперсидского ковра")
S(
"New players think that the action of HyperRogue takes place on a sphere. "
#ifdef MOBWEB
"This is not true -- the Tutorial in the native desktop version shows "
"the surface HyperRogue actually takes place on.",
#else
"This is not true -- the next slide will show the surface HyperRogue "
"actually takes place on.\n\n"
"Use arrow keys to rotate the model, and Page Up/Down to zoom.\n\n"
"If you do not see anything, press '5' to try a safer renderer.",
#endif
"Новички иногда думают, что действие в HyperRogue происходит на сфере. "
#ifdef MOBWEB
"Это неправда -- Руководство в компьютерной версии покажет тебе "
"настоящую поверхность HyperRogue."
#else
"Это неправда -- на следующем слайде показана настоящая поверхность HyperRogue.\n\n"
"Используйте стрелки, чтобы поворачивать модель, и Page Up/Down, чтобы менять размер.\n\n"
"Если ничего не видно, нажми '5' для безопасного визуализатора."
#endif
)
S("Expansion", "Расширение")
S(
"The next slide shows the number of cells in distance 1, 2, 3, ... from you. "
"It grows exponentially: there are more than 10^100 cells "
"in radius 1000 around you, and you will move further away during the game!\n\n"
"This is extremely important in the design of HyperRogue. "
"HyperRogue has many navigational puzzles -- what would be simple in Euclidean world "
"is extremely tricky "
"in hyperbolic geometry (you want to reach a specific location 20 cells away, "
"which of the thousands of possible directions should you take?); however, other things virtually impossible in Euclidean "
"world become easy in HyperRogue. "
"HyperRogue had to be specially designed so that it is impossible to grind the "
"infinite world. There are almost no permanent upgrades; collecting treasures "
"brings you benefits, but trying to get too many of the same kind is extremely dangerous.",
"Следующий слайд покажет количество клеток на расстоянии 1, 2, 3, ... от тебя. "
"Оно растёт экспоненциально: в радиусе 1000 клеток от тебя находится более 10^100 клеток, "
"а ты за время игры уйдёшь гораздо дальше!\n\n"
"Это очень важно для HyperRogue. Здесь есть много загадок навигации -- "
"то, что очень просто в евклидовой геометрии, становится невероятно сложным "
"в гиперболической геометрии (ты хочешь попасть в определённую клетку на расстоянии 20 от тебя, "
"какое из тысяч направлений выбрать?); однако другие вещи, практически невозможные в евклидовом мире, "
"здесь очень просты. Игра HyperRogue сделана так, чтобы было невозможно просто "
"захватывать бесконечный мир -- практически нет постоянных улучшений, "
"сбор сокровищ даёт преимущества, но собирать много сокровищ одного вида "
"весьма опасно.")
S("Tiling and Tactics", "Геометрия и тактика")
S(
"The tactics of fighting simple monsters, such as the Yetis from the Icy Lands, "
"might appear shallow, but hyperbolic geometry is essential even there. "
"In the next slide, you are attacked by two monsters at once. "
"You can make them line up simply by "
"running away in a straight line. "
"Press '2' to try the same in the Euclidean world -- it is impossible.",
"Тактика боя с простыми монстрами, такими как Йети из Ледяной земли, может "
"показаться обычной, но геометрия важна и здесь. "
"На следующем слайде тебя атакуют сразу два монстра. Ты можешь "
"справиться с ними, просто отходя по прямой. Нажми '2', чтобы попробовать сделать "
"то же самое в евклидовом мире -- ничего не выйдет.")
S("Straight Lines", "Прямые линии")
S("Hyperbolic geometry has been discovered by the 19th century mathematicians who "
"wondered about the nature of paralellness. Take a line L and a point A. "
"Can a world exist where there is more than one line passing through A "
"which does not cross L?\n\n"
"The Icy Land will be very dangerous if you have lots of Ice Diamonds -- "
"lots of Yetis and Ice Wolves hunting you! But the other lands, where "
"you have no treasures yet, will still be (relatively) safe.\n\n"
"Wander further, and you should find Crossroads quickly -- "
"the Great Walls are straight lines, and indeed, they work differently than in "
"Euclidean. On the other side of Great Walls, you see other lands -- "
"there are about 50 lands in HyperRogue, based "
"on different mechanics and aspects of hyperbolic geometry.",
"Гиперболическая геометрия была открыта в 19 веке математиками, которые интересовались "
"природой параллельности. Возьмём прямую L и точку A. Может ли существовать "
"мир, в котором есть более чем одна прямая, проходящая через A "
"и не пересекающая L?\n\n"
"Ледяная земля становится очень опасной, когда у тебя много Ледяных алмазов -- "
"много Йети и Ледяных волков охотятся на тебя! "
"Но другие земли, где у тебя нет сокровищ, всё ещё (относительно) безопасны.\n\n"
"Исследуй дальше, и ты скоро найдёшь Перекрёсток -- Великие стены являются "
"прямыми, и они ведут себя не так, как в евклидовой геометрии. "
"По другую сторону от Великих стен ты видишь другие земли -- их около 50, "
"основанных на разных особенностях гиперболической геометрии.")
S("Running Dogs", "Бегущие собаки")
S(
"To learn more about straight lines, "
"wander further, and you should find the Land of Eternal Motion. "
"Try to run in a straight line, with a Running Dog next to you. "
"Even though the Running Dog runs at the same speed as you, "
"it will appear to go slower -- this is because you are running "
"in a straight line, and the Running Dog has to run in a curve "
"called an equidistant.\n\n"
#ifdef MAC
"Remember that you can click with right Shift on anything to get more information.",
#else
"Remember that you can right click on anything to get more information.",
#endif
"Чтобы узнать больше о прямых линиях, "
"найди Землю вечного движения. "
"Попробуй двигаться по прямой вместе с собакой, бегущей рядом. "
"Хотя вы бежите с равной скоростью, она будет "
"отставать -- дело в том, что ты бежишь по прямой, "
"а собака -- по кривой, называемой эквидистантой.\n\n")
S("Equidistants", "Эквидистанты")
S(
"Equidistants are curves which are at some fixed distance from a "
"straight line. Some lands in HyperRogue are based on equidistants; "
"you should see them after wandering a bit more.\n\n"
"This tutorial gives you freedom to go wherever you choose, "
"but we do not recommend going deep into the Dungeon or the Ocean -- "
"getting back might be difficult.",
"Эквидистантой называется кривая, состоящая из точек на фиксированном расстоянии от прямой. "
"Некоторые земли основаны на эквидистантах; "
"ты увидишь их через некоторое время.\n\n"
"Это руководство позволяет идти куда угодно, "
"но мы не рекомендуем забираться глубоко в Подземелье или Океан -- "
"возвращение может оказаться трудным.")
S("Circles", "Окружности")
S(
"Circles are strange in hyperbolic geometry too. "
"Look for the Castle of Camelot in the Crossroads; "
"the Round Table inside is a circle of radius 28. "
"Finding its center is a difficult challenge.\n\n"
"Press '5' to cheat by seeing the smaller circles too.\n\n"
"Note: Camelot and some other lands are unlocked earlier in the Tutorial than in a real game.",
"Окружности в гиперболической геометрии тоже странные. "
"Найдите замок Камелот на Перекрёстке; Круглый стол внутри него "
"является кругом радиуса 28. Найти его центр -- "
"трудная задача.\n\n"
"Нажмите '5' чтобы получить подсказку -- увидеть меньшие круги.\n\n"
"Внимание: Камелот и некоторые другие земли открываются в Руководстве раньше, "
"чем в обычной игре.")
S("Horocycles", "Орициклы")
S("Horocycles are similar to circles, but you cannot reach their center at all -- "
"they can be understood as limit circles of infinite radius centered in some point "
"in infinity (also called an ideal point).\n\n"
"Go to R'Lyeh, and you should quickly find a Temple of Cthulhu there. "
"Each circle of columns is actually a horocycle. Horocycles in a given "
"temple are concentric, and there is an infinite number of them.",
"Орициклы похожи на круги, но достичь их центра невозможно -- "
"их можно понимать как предельные круги бесконечного радиуса с центром "
"в точке на бесконечности (такие точки называются идеальными).\n\n"
"Иди в Р'Льех и найди Храм Ктулху. Каждый круг колонн "
"на самом деле орицикл. Орициклы в храме концентричны, и их число бесконечно.")
S("Half-plane model", "Модель полуплоскости")
S("The game is normally displayed in the so called Poincaré disk model, "
"which is a kind of a map of the infinite hyperbolic world. "
"There are many projections of Earth, but since Earth is curved, "
"all of them have to distort distances or angles in some way -- "
"the same is true in hyperbolic geometry. "
"The next slide shows another model, called the Poincaré upper half-plane model. In this model, "
"horocycles centered at one specific ideal point are drawn as straight lines.",
"Обычно игра отображается в так называемой модели Пуанкаре в диске, карте "
"бесконечного гиперболического мира. Есть много проекций Земли, "
"но, так как она искривлённая, все они искажают расстояния или углы "
"каким-то образом -- то же самое верно и здесь. "
"Следующий слайд изображает другую модель, называемую моделью верхней полуплоскости. "
"В этой модели орициклы с центром в одной определённой идеальной точке изображаются "
"прямыми линиями.")
S("Curvature", "Кривизна")
S("gain Orb of the Sword", "получи Сферу меча")
S(
"Now, go to the Burial Grounds and find an Orb of the Sword. The Sword appears to "
"always be facing in the same direction whatever you do, and it appears that "
"you have to rotate the sword to excavate the treasures; "
"yet, it is possible to excavate them! You migth have already noticed "
"that the world rotates after you move around a loop and return to an old "
"place.\n\n"
"This is related to the fact that the world of HyperRogue is curved, and "
"the sum of angles in a triangle is not equal to 180 degrees.",
"Теперь иди в Курганы и найди Сферу меча. Кажется, что меч всегда направлен "
"в одну и ту же сторону, что бы ты не делал%E0, а для того, чтобы добыть сокровища, "
"нужно его повернуть. И его можно повернуть! Может быть, ты уже заметил%E0, "
"что мир повернётся, если пройти по петле и вернуться на то же место.\n\n"
"Это связано с тем, что мир HyperRogue искривлён, и сумма углов треугольника "
"не равна 180 градусам.")
S("Periodic patterns", "Периодические узоры")
S("Hyperbolic geometry yields much more interesting periodic patterns "
"than Euclidean.",
"Гиперболическая геометрия даёт больше интересных периодических шаблонов, "
"чем евклидова.")
S("Periodic patterns: application", "Приложение периодических узоров")
S("Many lands in HyperRogue are based around periodic patterns. "
"For example, both Zebra and Windy Plains are based on the pattern "
"shown in the previous slide. "
"Such lands often have tree-like nature.",
"Wiele krain jest opartych na okresowych wzorach. Na przykład Zebra "
"i Wietrzna Równina są obie oparte na wzorze z poprzedniego slajdu. "
"Krainy takie mają zwykle drzewiastą strukturę.")
S("Fractal landscapes", "Фрактальные пейзажи")
S("On the following slide, the colors change smoothly in the whole infinite world. "
"Again, this works better than in Euclidean geometry.",
"На следующем слайде цвета изменяются плавно по всему бесконечному миру. "
"Опять же, это работает лучше, чем в евклидовой геометрии.")
S("Fractal landscapes: application", "Приложение фрактальных пейзажей")
S("create a baby tortoise", "создай черепашку")
S(
"This is applied in HyperRogue to create landscapes, such as the chasms in the "
"land of Reptiles or the Dragon Chasms, which you should find quickly. "
"Also in the Dragon Chasms, you can find a Baby Tortoise, and try to find "
"a matching adult tortoise in the Galápagos. "
"There are over two millions of species, but since there is so much space in "
"hyperbolic geometry, finding a matching tortoise is possible. The brighter "
"the color in Galápagos is, the more aspects of the tortoises in the given "
"area are matching.",
"Фракталы применяются для создания пропастей в земле Рептилий "
"и в Драконьей бездне, которые ты быстро найдёшь. "
"Также в Драконьей бездне ты можешь найти Черепашку и попробовать "
"найти её родителей на Галапагосах. Там живёт более двух миллионов видов, "
"но в гиперболической геометрии очень много места, и найти её вид "
"вполне возможно. Чем ярче цвет клетки, "
"тем больше параметров совпадает с тем видом, что ты ищешь.")
S("Poincaré Ball model", "Сферическая модель Пуанкаре")
S(
"The Poincaré disk model is a model of a hyperbolic *plane* -- you "
"might wonder why are the walls rendered in 3D then.\n\n"
"HyperRogue actually assumes that the floor level is an equidistant surface "
"in a three-dimensional hyperbolic world, and the camera is placed above the "
"plane that the surface is equidistant to (which boils down to showing "
"the floor level in Poincaré disk model).\n\n"
"This is shown on the next slide, in the Poincaré ball model, which is "
"the 3D analog of the Poincaré disk model.",
"Модель диска Пуанкаре -- это модель гиперболической *плоскости*, и ты "
"мог задуматься, почему же стены отображаются в 3D.\n\n"
"HyperRogue на самом деле предполагает, что уровень пола -- это "
"эквидистанта в трёхмерном гиперболическом мире, а камера находится выше плоскости, "
"эквидистантой к которой является поверхность -- таким образом пол выглядит "
"в точности как в модели Пуанкаре.\n\n"
"Это показано на следующем слайде, в модели сферы, трёхмерном аналоге модели диска.")
S("Hyperboloid model", "Модель гиперболоида")
S(
"Let's see more models of the hyperbolic plane. "
"This model uses a hyperboloid in the Minkowski geometry; "
"it is used internally by HyperRogue.",
"Давай посмотрим на другие модели. Эта модель использует гиперболоид в геометрии Минковского; "
"HyperRogue внутренне использует эту модель.")
S("Beltrami-Klein model", "Модель Бельтрами-Клейна")
S(
"This model renders straight lines as straight, but it distorts angles.",
"В этой модели прямые линии остаются прямыми, но углы искажаются.")
S("Gans model", "Модель Ганса")
S(
"Yet another model, which corresponds to orthographic projection of the "
"sphere. Poincaré disk model, Beltrami-Klein model, and the Gans "
"model are all obtained by looking at either the hyperboloid model or an "
"equidistant surface from various distances.",
"Ещё одна модель, соответствующая ортогональной проекции сферы. Модели диска, "
"Клейна и Ганса могут быть получены проекциями из модели гиперболоида "
"или из эквидистанты с разных расстояний.")
S("Band model", "Модель ленты")
S("render spiral", "нарисовать спираль")
S(
"The band model is the hyperbolic analog of the Mercator projection of the sphere: "
"a given straight line is rendered as a straight line, and the rest of the "
"world is mapped conformally, that is, angles are not distorted. "
"Here, we take the straight line connecting your starting point and your "
"current position -- usually the path taken by the player is surprisingly "
"close to a straight line. Press '8' to see this path.\n\n"
"If you want, press '5' to see it rendered as a spiral, although it takes lots of time and "
"memory.",
"Модель ленты -- гиперболический аналог проекции Меркатора сферы: "
"данная прямая отображается в прямую, а оставшаяся часть "
"отображается конформно, то есть углы не искажаются. "
"Здесь в качестве центральной прямой используется прямая, соединяющая точку старта и "
"твою текущую позицию -- обычно твой путь оказывается неожиданно близко "
"с прямой. Нажми '8', чтобы увидеть свой путь.\n\n"
"Если хочешь, нажми '5', чтобы отрисовать спираль, хотя это займёт много "
"времени и памяти.")
S("Conformal square model", "Конформный квадрат")
S("The world can be mapped conformally to a square too.",
"Также можно конформно отобразить мир на квадрат.")
S("Shoot'em up mode", "режим стрельбы")
S("In the shoot'em up mode, space and time is continuous. "
"You attack by throwing knives. "
"Very fun with two players!\n\n"
"There are other special modes too which change the gameplay or "
"focus on a particular challenge.",
"В режиме стрельбы пространство и время непрерывны. Ты атакуешь, "
"кидая ножи. Очень весело для двоих игроков!\n\n"
"Есть и другие специальные режимы, изменяющие игру или "
"концентрирующиеся на определённых задачах.")
S("THE END", "КОНЕЦ")
S("leave the Tutorial", "выйти из Руководства")
S(
"This tour shows just a small part of what you can see in the world of HyperRogue. "
"For example, "
"hyperbolic mazes are much nicer than their Euclidean counterparts. "
"Have fun exploring!\n\n"
"Press '5' to leave the tutorial mode.",
"Это путешествие показало лишь малую часть мира HyperRogue. Например, "
"гиперболические лабиринты намного приятнее евклидовых. Приятной игры!"
"Нажмите '5', чтобы выйти из режима Руководства."
)
#undef Orb

View File

@ -145,12 +145,14 @@ void parrep(string& x, string w, stringpar p) {
rep(x, "%abl"+w, N->n[0].abl);
rep(x, ""+w, choose3(N->n[0].genus, "ł", "ła", "ło"));
rep(x, "%łem"+w, choose3(N->n[0].genus, "łem", "łam", "łom"));
rep(x, "%łeś"+w, choose3(N->n[0].genus, "łeś", "łaś", "łoś"));
rep(x, "%ął"+w, choose3(N->n[0].genus, "ął", "ęła", "ęło"));
rep(x, "%ya"+w, choose3(N->n[0].genus, "y", "a", "e"));
rep(x, "%yą"+w, choose4(N->n[0].genus, "ego", "ą", "e", "y"));
rep(x, "%oa"+w, choose3(N->n[0].genus, "", "a", "o"));
rep(x, "%ymą"+w, choose3(N->n[0].genus, "ym", "ą", "ym"));
rep(x, "%go"+w, choose3(N->n[0].genus, "go", "", "je"));
rep(x, "%aka"+w, choose3(N->n[0].genus, "a", "ka", "a"));
}
else {
rep(x,"%"+w, p.v);

View File

@ -1878,9 +1878,9 @@ namespace linepatterns {
{patZebraTriangles, "zebra triangles", (int) 0x40FF4000},
{patZebraLines, "zebra lines", (int) 0xFF000000},
{patVine, "vineyard pattern", (int) 0x8438A400},
{patPalacelike, "firewall line", (int) 0xFF400000},
{patPalace, "firewall line: Palace", (int) 0xFFD50000},
{patPower, "firewall line: Power", (int) 0xFFFF0000},
{patPalacelike, "firewall lines", (int) 0xFF400000},
{patPalace, "firewall lines: Palace", (int) 0xFFD50000},
{patPower, "firewall lines: Power", (int) 0xFFFF0000},
{0, NULL, 0}
};

View File

@ -861,7 +861,7 @@ void showChangeMode() {
// gameplay modes
#ifdef TOUR
dialog::addBoolItem(XLAT("tutorial"), tour::on, 'T');
dialog::addBoolItem(XLAT("Tutorial"), tour::on, 'T');
#endif
dialog::addBoolItem(XLAT("Euclidean/elliptic mode"), (euclid || sphere), 'e');
@ -1212,6 +1212,8 @@ void handleEuclidean(int sym, int uni) {
if(landvisited[euclidland] && euclidland != laOceanWall) {
if(targetgeometry != geometry)
restartGame('g');
else
restartGame(tactic::on ? 't' : 0);
// disable PTM if chosen a land from the Euclidean menu
if(tactic::on) restartGame('t');
cmode = emNormal;

376
shmup.cpp
View File

@ -501,6 +501,13 @@ void pressaction(int id) {
actionspressed[id]++;
}
bool notremapped(int sym) {
int k = vid.scfg.keyaction[sym];
k /= 16;
if(k > 3) k--; else if(k==3) k = 2;
return k <= multi::players;
}
void handleInput(int delta) {
#ifndef NOSDL
double d = delta / 500.;
@ -902,7 +909,7 @@ multimap<cell*, monster*> monstersAt;
typedef multimap<cell*, monster*>::iterator mit;
vector<monster*> active;
vector<monster*> active, nonvirtual, additional;
cell *findbaseAround(hyperpoint p, cell *around) {
cell *best = around;
@ -917,6 +924,10 @@ cell *findbaseAround(hyperpoint p, cell *around) {
return best;
}
cell *findbaseAround(const transmatrix& H, cell *around) {
return findbaseAround(tC0(H), around);
}
cell *findbaseAroundRepeat(hyperpoint p, cell *around) {
while(true) {
cell *c = findbaseAround(p, around);
@ -925,12 +936,22 @@ cell *findbaseAroundRepeat(hyperpoint p, cell *around) {
}
}
cell *findbaseAroundRepeat(const transmatrix& H, cell *around) {
return findbaseAroundRepeat(tC0(H), around);
}
/* double distance(hyperpoint h) {
h = spintox(h) * h;
return asinh(h[2]);
} */
void fixelliptic(transmatrix& at) {
if(elliptic && at[2][2] < 0) {
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
at[i][j] = -at[i][j];
}
}
struct monster {
eMonster type;
cell *base;
@ -953,6 +974,7 @@ struct monster {
double swordangle; // sword angle wrt at
double vel; // velocity, for flail balls
double footphase;
bool isVirtual; // off the screen: gmatrix is unknown, and pat equals at
monster() {
dead = false; inBoat = false; parent = NULL; nextshot = 0;
@ -964,25 +986,46 @@ struct monster {
}
void findpat() {
pat = gmatrix[base] * at;
isVirtual = !gmatrix.count(base);
if(!isVirtual) pat = gmatrix[base] * at;
else pat = at;
}
cell *findbase(hyperpoint p) {
return findbaseAround(p, base);
cell *findbase(const transmatrix& T) {
if(isVirtual) {
cell *c = base;
auto cT = T;
virtualRebase(c, cT, true);
return c;
}
else return findbaseAround(T, base);
}
void rebasePat(transmatrix new_pat) {
void rebasePat(const transmatrix& new_pat) {
if(isVirtual) {
at = new_pat;
virtualRebase(this, true);
fixmatrix(at); pat = at;
return;
}
if(geometry == gQuotient) {
at = inverse(gmatrix[base]) * new_pat;
virtualRebase(this, true);
fixmatrix(at);
return;
}
pat = new_pat;
cell *c2 = findbase(pat*C0);
cell *c2 = findbase(pat);
// if(c2 != base) printf("rebase %p -> %p\n", base, c2);
base = c2;
at = inverse(gmatrix[c2]) * pat;
fixmatrix(at);
fixelliptic(at);
}
void rebaseAt(transmatrix new_at) {
/* void rebaseAt(const transmatrix& new_at) {
rebasePat(gmatrix[base] * new_at);
}
} */
bool trackroute(transmatrix goal, double spd) {
cell *c = base;
@ -1001,7 +1044,7 @@ struct monster {
// queuepoly(nat, shKnife, 0xFFFFFFC0);
cell *c2 = findbaseAround(nat*C0, c);
cell *c2 = findbaseAround(nat, c);
if(c2 != c && !passable_for(type, c2, c, P_CHAIN | P_ONPLAYER)) {
return false;
}
@ -1027,7 +1070,7 @@ struct monster {
// queuepoly(nat, shKnife, 0xFFFFFFC0);
cell *c2 = findbaseAround(nat*C0, c);
cell *c2 = findbaseAround(nat, c);
if(c2 != c) {
if(0) printf("old dist: %lf\n", (double) intval(nat*C0, gmatrix[c]*C0));
if(0) printf("new dist: %lf\n", (double) intval(nat*C0, gmatrix[c2]*C0));
@ -1087,8 +1130,7 @@ void killMonster(monster* m, eMonster who_kills, int flags = 0) {
}
void pushmonsters() {
for(int i=0; i<size(active); i++) {
monster *m = active[i];
for(monster *m: nonvirtual) {
m->notpushed = isPlayer(m) || m->dead || (m->base->monst && m->base->monst != m->type);
if(!m->notpushed) {
m->stk = m->base->monst;
@ -1098,8 +1140,8 @@ void pushmonsters() {
}
void popmonsters() {
for(int i=size(active)-1; i>=0; i--) {
monster *m = active[i];
for(int i=size(nonvirtual)-1; i>=0; i--) {
monster *m = nonvirtual[i];
if(!m->notpushed) {
if(m->type == m->base->monst)
m->base->monst = m->stk;
@ -1117,8 +1159,7 @@ void popmonsters() {
}
void degradeDemons() {
for(int i=0; i<size(active); i++) {
monster *m = active[i];
for(monster* m: nonvirtual) {
if(m->type == moGreater) m->type = moLesser;
if(m->stk == moGreater) m->type = moLesser;
}
@ -1176,7 +1217,7 @@ void awakenMimics(monster *m, cell *c2) {
if(isBullet(m) && i == 1) m2->at = m2->at * spin(M_PI); // no idea why this
active.push_back(m2);
additional.push_back(m2);
// if you don't understand it, don't worry,
// I don't understand it either
@ -1198,7 +1239,7 @@ void shootBullet(monster *m) {
bullet->parent = m;
bullet->pid = m->pid;
bullet->parenttype = m->type;
active.push_back(bullet);
additional.push_back(bullet);
if(markOrb(itOrbThorns)) {
monster* bullet = new monster;
@ -1208,7 +1249,7 @@ void shootBullet(monster *m) {
bullet->parent = m;
bullet->pid = m->pid;
bullet->parenttype = m->type;
active.push_back(bullet);
additional.push_back(bullet);
}
if(markOrb(itOrbThorns)) {
@ -1219,7 +1260,7 @@ void shootBullet(monster *m) {
bullet->parent = m;
bullet->pid = m->pid;
bullet->parenttype = m->type;
active.push_back(bullet);
additional.push_back(bullet);
}
if(markOrb(itOrbDash)) {
@ -1229,7 +1270,7 @@ void shootBullet(monster *m) {
bullet->type = moBullet;
bullet->parent = m;
bullet->parenttype = m->type;
active.push_back(bullet);
additional.push_back(bullet);
}
}
@ -1238,7 +1279,9 @@ void killThePlayer(eMonster m) {
}
monster *playerCrash(monster *who, hyperpoint where) {
if(who->isVirtual) return NULL;
for(int j=0; j<players; j++) if(pc[j]!=who) {
if(pc[j]->isVirtual) continue;
double d = intval(pc[j]->pat*C0, where);
if(d < 0.1 * SCALE2 || d > 100) return pc[j];
}
@ -1401,7 +1444,9 @@ void movePlayer(monster *m, int delta) {
double mturn = 0, mgo = 0, mdx = 0, mdy = 0;
bool shotkey = false, dropgreen = false, facemouse = false;
if(facemouse) ;
if(facemouse) {
// silence warning that facemouse unused
}
int b = 16*tableid[cpid];
for(int i=0; i<8; i++) if(actionspressed[b+i]) playermoved = true;
@ -1535,11 +1580,11 @@ void movePlayer(monster *m, int delta) {
// spin(span[igo]) * xpush(playergo[cpid]) * spin(-span[igo]);
c2 = m->findbase(nat*C0);
c2 = m->findbase(nat);
// don't have several players in one spot
// also don't let them run too far from each other!
monster* crashintomon = playerCrash(m, nat*C0);
monster* crashintomon = m->isVirtual ? NULL : playerCrash(m, nat*C0);
if(crashintomon) go = false;
if(go && c2 != m->base) {
@ -1581,7 +1626,7 @@ void movePlayer(monster *m, int delta) {
for(int di=-1; di<2; di+=2) {
cell *c = getMovR(c2, sd+di);
if(!c) continue;
if(!gmatrix.count(c)) continue;
if(m->isVirtual || !gmatrix.count(c)) continue;
double d = intval(gmatrix[c] * C0, m->pat * C0);
// printf("di=%d d=%lf\n", di, d);
if(d<bestd) bestd=d, subdir = di;
@ -1719,11 +1764,10 @@ void movePlayer(monster *m, int delta) {
playerfire[cpid] = false;
if(items[itOrbHorns]) {
if(items[itOrbHorns] && !m->isVirtual) {
hyperpoint H = hornpos(cpid);
for(int j=0; j<size(active); j++) {
monster* m2 = active[j];
for(monster *m2: nonvirtual) {
if(m2 == m) continue;
double d = intval(m2->pat*C0, H);
@ -1737,13 +1781,12 @@ void movePlayer(monster *m, int delta) {
}
}
for(int b=0; b<2; b++) if(sword::orbcount(b)) {
for(int b=0; b<2; b++) if(sword::orbcount(b) && !m->isVirtual) {
for(double d=0; d<=1.001; d += .1) {
hyperpoint H = swordpos(cpid, b, d);
for(int j=0; j<size(active); j++) {
monster* m2 = active[j];
for(monster *m2: nonvirtual) {
if(m2 == m) continue;
double d = intval(m2->pat*C0, H);
@ -1799,7 +1842,16 @@ monster *getPlayer() {
return pc[cpid];
}
void virtualize(monster *m) {
if(quotient) forCellCM(c2, m->base) if(!gmatrix.count(c2)) {
m->isVirtual = true;
m->pat = m->at;
return;
}
}
void moveMimic(monster *m) {
virtualize(m);
transmatrix nat = m->pat;
cpid = m->pid;
m->footphase = getPlayer()->footphase;
@ -1807,7 +1859,7 @@ void moveMimic(monster *m) {
// no need to care about Mirror images, as they already have their 'at' matrix reversed :|
nat = nat * spin(playerturn[cpid]) * xpush(playergo[cpid]);
cell *c2 = m->findbase(nat*C0);
cell *c2 = m->findbase(nat);
if(c2 != m->base && !passable(c2, m->base, P_ISPLAYER | P_MIRROR))
killMonster(m, moNone);
else {
@ -1827,7 +1879,7 @@ void moveMimic(monster *m) {
c2->wall = waNone;
}
if(c2->cpdist >= 6)
if(!quotient && c2->cpdist >= 6)
m->dead = true;
}
@ -1846,9 +1898,9 @@ bool verifyTeleport() {
}
void destroyMimics() {
for(int i=0; i<size(active); i++)
if(isMimic(active[i]->type))
active[i]->dead = true;
for(monster *m: active)
if(isMimic(m->type))
m->dead = true;
}
void teleported() {
@ -1868,7 +1920,7 @@ void shoot(eItem it, monster *m) {
bullet->pid = m->pid;
bullet->parenttype = m->type;
items[it]--;
active.push_back(bullet);
additional.push_back(bullet);
}
eItem targetRangedOrbKey(orbAction a) {
@ -1887,8 +1939,7 @@ eItem targetRangedOrbKey(orbAction a) {
}
mousetarget = NULL;
for(int j=0; j<size(active); j++) {
monster* m2 = active[j];
for(monster *m2: nonvirtual) {
if(m2->dead) continue;
#ifdef ROGUEVIZ
if(rogueviz::virt(m2)) continue;
@ -1956,8 +2007,11 @@ int speedfactor() {
void moveBullet(monster *m, int delta) {
cpid = m->pid;
m->findpat();
virtualize(m);
transmatrix nat0 = m->pat;
transmatrix nat = m->pat;
if(isReptile(m->base->wall)) m->base->wparam = reptilemax();
@ -1976,11 +2030,11 @@ void moveBullet(monster *m, int delta) {
m->vel = 1/200.;
else if(m->type == moTongue) {
m->vel = 1/1500.;
if(!m->parent || intval(nat*C0, m->parent->pat*C0) > SCALE2 * 0.4)
if(m->isVirtual || !m->parent || intval(nat*C0, m->parent->pat*C0) > SCALE2 * 0.4)
m->dead = true;
}
nat = nat * xpush(delta * SCALE * m->vel / speedfactor());
cell *c2 = m->findbase(nat*C0);
cell *c2 = m->findbase(nat);
if(isActivable(c2)) activateActiv(c2, true);
@ -2023,14 +2077,13 @@ void moveBullet(monster *m, int delta) {
m->rebasePat(nat);
// destroy stray bullets
for(int i=0; i<m->base->type; i++)
if(!quotient) for(int i=0; i<m->base->type; i++)
if(!m->base->mov[i] || !gmatrix.count(m->base->mov[i]))
m->dead = true;
// items[itOrbWinter] = 100; items[itOrbLife] = 100;
for(int j=0; j<size(active); j++) {
monster* m2 = active[j];
if(!m->isVirtual) for(monster* m2: nonvirtual) {
if(m2 == m || (m2 == m->parent && m->vel >= 0) || m2->parent == m->parent) continue;
// Flailers only killable by themselves
@ -2137,7 +2190,7 @@ bool dragonbreath(cell *dragon) {
bullet->type = moFireball;
bullet->parent = bullet;
bullet->pid = randplayer;
active.push_back(bullet);
additional.push_back(bullet);
return true;
}
@ -2195,15 +2248,16 @@ void moveMonster(monster *m, int delta) {
else if(isBull(m->type))
step *= 1.5;
if(items[itOrbBeauty]) {
if(items[itOrbBeauty] && !m->isVirtual) {
bool nearplayer = false;
for(int pid=0; pid<players; pid++) {
for(int pid=0; pid<players; pid++) if(!pc[pid]->isVirtual) {
double dist = intval(pc[pid]->pat*C0, m->pat*C0);
if(dist < SCALE2) nearplayer = true;
}
if(nearplayer) markOrb(itOrbBeauty), step /= 2;
}
if(m->isVirtual) return;
transmatrix nat = m->pat;
if(stunned) {
@ -2221,18 +2275,18 @@ void moveMonster(monster *m, int delta) {
else {
if(m->type == moSleepBull) {
for(int j=0; j<size(active); j++) if(active[j]!=m && active[j]->type != moBullet) {
monster* m2 = active[j];
if(m->type == moSleepBull && !m->isVirtual) {
for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet) {
double d = intval(m2->pat*C0, nat*C0);
if(d < SCALE2*3 && m2->type == moPlayer) m->type = moRagingBull;
}
}
if(m->type == moWitchFlash) for(int pid=0; pid<players; pid++) {
if(pc[pid]->isVirtual) continue;
if(m->isVirtual) continue;
bool okay = intval(pc[pid]->pat*C0, m->pat*C0) < 2 * SCALE2;
for(int i=0; i<size(active); i++) {
monster *m2 = active[i];
for(monster *m2: nonvirtual) {
if(m2 != m && isWitch(m2->type) && intval(m2->pat*C0, m->pat*C0) < 2 * SCALE2)
okay = false;
}
@ -2247,19 +2301,19 @@ void moveMonster(monster *m, int delta) {
}
if(isBug(m->type)) {
vector<monster*> bugtargets;
for(int i=0; i<size(active); i++)
if(!isBullet(active[i]))
if(active[i]->type != m->type)
if(!isPlayer(active[i]) || !invismove)
if(!active[i]->dead)
bugtargets.push_back(active[i]);
for(monster *m2: nonvirtual)
if(!isBullet(m2))
if(m2->type != m->type)
if(!isPlayer(m2) || !invismove)
if(!m2->dead)
bugtargets.push_back(m2);
closerTo = m->pat * C0;
sort(bugtargets.begin(), bugtargets.end(), closer);
for(int i=0; i<size(bugtargets); i++)
if(m->trackroute(bugtargets[i]->pat, step)) {
goal = bugtargets[i]->pat;
for(monster *m2: bugtargets)
if(m->trackroute(m2->pat, step)) {
goal = m2->pat;
direct = true;
break;
}
@ -2340,8 +2394,8 @@ void moveMonster(monster *m, int delta) {
}
}
if(m->type == moVampire) for(int i=0; i<players; i++)
if(intval(m->pat*C0, pc[i]->pat*C0) < SCALE2 * 2) {
if(m->type == moVampire && !m->isVirtual) for(int i=0; i<players; i++)
if(!pc[i]->isVirtual && intval(m->pat*C0, pc[i]->pat*C0) < SCALE2 * 2) {
for(int i=0; i<ittypes; i++)
if(itemclass(eItem(i)) == IC_ORB && items[i] && items[itOrbTime] && !orbused[i])
orbused[i] = true;
@ -2384,6 +2438,7 @@ void moveMonster(monster *m, int delta) {
igo++; goto igo_retry; }
for(int i=0; i<multi::players; i++) for(int b=0; b<2; b++) if(sword::orbcount(b)) {
if(pc[i]->isVirtual) continue;
hyperpoint H = swordpos(i, b, 1);
double d = intval(H, nat*C0);
if(d < SCALE2 * 0.12) { igo++; goto igo_retry; }
@ -2393,10 +2448,9 @@ void moveMonster(monster *m, int delta) {
monster* crashintomon = NULL;
for(int j=0; j<size(active); j++) if(active[j]!=m && active[j]->type != moBullet) {
monster* m2 = active[j];
if(!m->isVirtual) for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet) {
double d = intval(m2->pat*C0, nat*C0);
if(d < SCALE2 * 0.1) crashintomon = active[j];
if(d < SCALE2 * 0.1) crashintomon = m2;
}
for(int i=0; i<players; i++)
@ -2423,7 +2477,7 @@ void moveMonster(monster *m, int delta) {
if(crashintomon) { igo++; goto igo_retry; }
cell *c2 = m->findbase(nat*C0);
cell *c2 = m->findbase(nat);
if(m->type == moButterfly && !passable_for(m->type, c2, m->base, P_CHAIN)) {
igo++; goto igo_retry;
@ -2446,7 +2500,7 @@ void moveMonster(monster *m, int delta) {
bullet->parent = m;
bullet->parenttype = m->type;
bullet->pid = whichPlayerOn(c2);
active.push_back(bullet);
additional.push_back(bullet);
return;
}
}
@ -2494,10 +2548,10 @@ void moveMonster(monster *m, int delta) {
cell *c3 = m->base->mov[i];
if(dirfromto(c3, c2) != -1 && c3->wall == waFreshGrave && gmatrix.count(c3)) {
bool monstersNear = false;
for(int i=0; i<size(active); i++) {
if(active[i] != m && intval(active[i]->pat*C0, gmatrix[c3]*C0) < SCALE2 * .3)
for(monster *m2: nonvirtual) {
if(m2 != m && intval(m2->pat*C0, gmatrix[c3]*C0) < SCALE2 * .3)
monstersNear = true;
if(active[i] != m && intval(active[i]->pat*C0, gmatrix[c2]*C0) < SCALE2 * .3)
if(m2 != m && intval(m2->pat*C0, gmatrix[c2]*C0) < SCALE2 * .3)
monstersNear = true;
}
if(!monstersNear) {
@ -2510,7 +2564,7 @@ void moveMonster(monster *m, int delta) {
undead->parenttype = m->type;
undead->pid = 0;
undead->findpat();
active.push_back(undead);
additional.push_back(undead);
undead = new monster;
undead->base = c3;
@ -2520,7 +2574,7 @@ void moveMonster(monster *m, int delta) {
undead->parenttype = m->type;
undead->findpat();
undead->pid = 0;
active.push_back(undead);
additional.push_back(undead);
c3->wall = waAncientGrave;
addMessage(XLAT("%The1 raises some undead!", m->type));
@ -2581,7 +2635,7 @@ void moveMonster(monster *m, int delta) {
bullet->at = m->at;
bullet->type = moFireball;
bullet->parent = m;
active.push_back(bullet);
additional.push_back(bullet);
bullet->pid = directi;
if(m->type == moPyroCultist)
m->type = moCultist;
@ -2596,10 +2650,10 @@ void moveMonster(monster *m, int delta) {
bullet->parent = m;
bullet->parenttype = moOutlaw;
bullet->pid = directi;
active.push_back(bullet);
additional.push_back(bullet);
m->nextshot = curtime + 1500;
}
for(int i=0; i<players; i++)
for(int i=0; i<players; i++) if(!pc[i]->isVirtual)
if((m->type == moAirElemental) && curtime >= m->nextshot && intval(m->pat*C0, pc[i]->pat*C0) < SCALE2 * 2) {
monster* bullet = new monster;
bullet->base = m->base;
@ -2607,16 +2661,16 @@ void moveMonster(monster *m, int delta) {
bullet->type = moAirball;
bullet->parent = m;
bullet->pid = i;
active.push_back(bullet);
additional.push_back(bullet);
m->nextshot = curtime + 1500;
}
for(int i=0; i<players; i++)
for(int i=0; i<players; i++) if(!pc[i]->isVirtual)
if(m->type == moTortoise && tortoise::seek() && !tortoise::diff(getBits(m->torigin)) && intval(m->pat*C0, pc[i]->pat*C0) < SCALE2) {
items[itBabyTortoise] += 4;
m->dead = true;
addMessage(XLAT(playergender() == GEN_F ? "You are now a tortoise heroine!" : "You are now a tortoise hero!"));
}
for(int i=0; i<players; i++)
for(int i=0; i<players; i++) if(!pc[i]->isVirtual)
if(m->type == moFlailer && curtime >= m->nextshot &&
intval(m->pat*C0, pc[i]->pat*C0) < SCALE2 * 2) {
m->nextshot = curtime + 3500;
@ -2627,16 +2681,45 @@ void moveMonster(monster *m, int delta) {
bullet->parent = m;
bullet->vel = 1/400.0;
bullet->pid = i;
active.push_back(bullet);
additional.push_back(bullet);
break;
}
}
}
void activateMonstersAt(cell *c) {
pair<mit, mit> p =
monstersAt.equal_range(c);
for(mit it = p.first; it != p.second;) {
mit itplus = it;
itplus++;
active.push_back(it->second);
monstersAt.erase(it);
it = itplus;
}
if(c->monst && isMimic(c->monst)) c->monst = moNone;
// mimics are awakened by awakenMimics
if(c->monst && !isIvy(c) && !isWorm(c) && !isMutantIvy(c) && !isKraken(c->monst) && c->monst != moPrincess) {
// awaken as a monster
monster *enemy = new monster;
enemy->at = Id;
enemy->base = c;
if(enemy->type == moButterfly)
enemy->torigin = createMov(c, (c->mondir + 419) % c->type);
enemy->torigin = c;
enemy->type = c->monst;
enemy->hitpoints = c->hitpoints;
if(c->wall == waBoat && isLeader(c->monst))
enemy->inBoat = true, c->wall = waSea;
c->monst = moNone;
active.push_back(enemy);
}
}
void turn(int delta) {
lmousetarget = NULL;
if(mousetarget && intval(mouseh, mousetarget->pat*C0) < 0.1)
if(mousetarget && !mousetarget->isVirtual && intval(mouseh, mousetarget->pat*C0) < 0.1)
lmousetarget = mousetarget;
if(delta > 1000) delta = 1000;
@ -2650,36 +2733,12 @@ void turn(int delta) {
invismove = (curtime >= visibleAt) && markOrb(itOrbInvis);
// detect active monsters
for(unordered_map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
cell *c = it->first;
pair<mit, mit> p =
monstersAt.equal_range(c);
for(mit it = p.first; it != p.second;) {
mit itplus = it;
itplus++;
active.push_back(it->second);
monstersAt.erase(it);
it = itplus;
}
if(c->monst && isMimic(c->monst)) c->monst = moNone;
// mimics are awakened by awakenMimics
if(c->monst && !isIvy(c) && !isWorm(c) && !isMutantIvy(c) && !isKraken(c->monst) && c->monst != moPrincess) {
// awaken as a monster
monster *enemy = new monster;
enemy->at = Id;
enemy->base = c;
if(enemy->type == moButterfly)
enemy->torigin = createMov(c, (c->mondir + 419) % c->type);
enemy->torigin = c;
enemy->type = c->monst;
enemy->hitpoints = c->hitpoints;
if(c->wall == waBoat && isLeader(c->monst))
enemy->inBoat = true, c->wall = waSea;
c->monst = moNone;
active.push_back(enemy);
}
}
if(quotient)
for(cell *c: currentmap->allcells()) activateMonstersAt(c);
else
for(unordered_map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++)
activateMonstersAt(it->first);
/* printf("size: gmatrix = %ld, active = %ld, monstersAt = %ld, delta = %d\n",
gmatrix.size(), active.size(), monstersAt.size(),
delta); */
@ -2688,14 +2747,15 @@ void turn(int delta) {
for(int i=0; i<motypes; i++) exists[i] = false;
for(int i=0; i<size(active); i++) {
monster* m = active[i];
nonvirtual.clear();
for(monster *m: active) {
m->findpat();
if(m->isVirtual) continue;
else nonvirtual.push_back(m);
exists[movegroup(m->type)] = true;
}
for(int i=0; i<size(active); i++) {
monster* m = active[i];
for(monster *m: active) {
switch(m->type) {
case moPlayer:
@ -2710,8 +2770,7 @@ void turn(int delta) {
}
}
for(int i=0; i<size(active); i++) {
monster* m = active[i];
for(monster *m: active) {
if(isMimic(m->type))
moveMimic(m);
}
@ -2751,9 +2810,9 @@ void turn(int delta) {
// move monsters of this type
for(int i=0; i<size(active); i++)
if(movegroup(active[i]->type) == t)
moveMonster(active[i], delta);
for(monster *m: nonvirtual)
if(movegroup(m->type) == t)
moveMonster(m, delta);
}
if(shmup::on) {
@ -2851,14 +2910,18 @@ void turn(int delta) {
}
}
for(monster *m: additional) active.push_back(m); additional.clear();
// deactivate all monsters
for(int i=0; i<size(active); i++)
if(active[i]->dead && active[i]->type != moPlayer) {
for(int j=0; j<size(active); j++) if(active[j]->parent == active[i])
active[j]->parent = active[i]->parent;
delete active[i];
for(monster *m: active)
if(m->dead && m->type != moPlayer) {
for(monster *m2: active) if(m2->parent == m)
m2->parent = m->parent;
delete m;
}
else {
m->store();
}
else active[i]->store();
active.clear();
@ -3043,7 +3106,7 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans
void clearMonsters() {
for(mit it = monstersAt.begin(); it != monstersAt.end(); it++)
delete(it->second);
for(int i=0; i<size(active); i++) delete active[i];
for(monster *m: active) delete m;
monstersAt.clear();
active.clear();
}
@ -3066,9 +3129,9 @@ bool playerInBoat(int i) {
}
void destroyBoats(cell *c) {
for(int i=0; i<size(active); i++)
if(active[i]->base == c && active[i]->inBoat)
active[i]->inBoat = false;
for(monster *m: active)
if(m->base == c && m->inBoat)
m->inBoat = false;
}
transmatrix calc_relative_matrix(cell *c, heptagon *h1) {
@ -3167,34 +3230,34 @@ transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) {
return gm * where;
}
void virtualRebase(shmup::monster *m, bool tohex) {
void virtualRebase(cell*& base, transmatrix& at, bool tohex) {
if(euclid || sphere) {
again:
forCellCM(c2, m->base) {
transmatrix newat = inverse(ggmatrix(c2)) * ggmatrix(m->base) * m->at;
forCellCM(c2, base) {
transmatrix newat = inverse(ggmatrix(c2)) * ggmatrix(base) * at;
if(hypot(tC0(newat)[0], tC0(newat)[1])
< hypot(tC0(m->at)[0], tC0(m->at)[1])) {
m->at = newat;
m->base = c2;
< hypot(tC0(at)[0], tC0(at)[1])) {
at = newat;
base = c2;
goto again;
}
}
fixelliptic(at);
return;
}
while(true) {
if(m->base->type == 6) {
cell *c7 = m->base->master->c7;
for(int d=0; d<7; d++) if(c7->mov[d] == m->base)
m->at = hexmove[d] * m->at;
m->base = c7;
if(base->type == 6) {
cell *c7 = base->master->c7;
for(int d=0; d<7; d++) if(c7->mov[d] == base)
at = hexmove[d] * at;
base = c7;
}
double currz = (m->at * C0)[2];
double currz = (at * C0)[2];
heptagon *h = m->base->master;
heptagon *h = base->master;
cell *newbase = NULL;
@ -3207,7 +3270,7 @@ void virtualRebase(shmup::monster *m, bool tohex) {
heptspin hs2 = hsstep(hs, 0);
transmatrix V2 = spin((purehepta?M_PI:0)-hs2.spin*2*M_PI/7) * invheptmove[d];
if(purehepta) V2 = V2 * spin(M_PI);
double newz = (V2 * m->at * C0) [2];
double newz = (V2 * at * C0) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
@ -3217,9 +3280,9 @@ void virtualRebase(shmup::monster *m, bool tohex) {
if(!newbase) {
if(tohex && !purehepta) for(int d=0; d<7; d++) {
cell *c = createMov(m->base, d);
transmatrix V2 = spin(-m->base->spn(d)*2*M_PI/6) * invhexmove[d];
double newz = (V2 *m->at * C0) [2];
cell *c = createMov(base, d);
transmatrix V2 = spin(-base->spn(d)*2*M_PI/6) * invhexmove[d];
double newz = (V2 *at * C0) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
@ -3227,19 +3290,22 @@ void virtualRebase(shmup::monster *m, bool tohex) {
}
}
if(newbase) {
m->base = newbase;
m->at = bestV * m->at;
base = newbase;
at = bestV * at;
}
break;
}
// printf("%p: rebase %p -> %p\n", m, m->base, newbase);
m->base = newbase;
m->at = bestV * m->at;
base = newbase;
at = bestV * at;
}
}
void virtualRebase(shmup::monster *m, bool tohex) {
virtualRebase(m->base, m->at, tohex);
}
}
#ifdef ROGUEVIZ