diff --git a/achievement.cpp b/achievement.cpp index b37da17f..9e4f4caf 100644 --- a/achievement.cpp +++ b/achievement.cpp @@ -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 diff --git a/complex.cpp b/complex.cpp index eef8d921..8bb67366 100644 --- a/complex.cpp +++ b/complex.cpp @@ -1101,6 +1101,7 @@ namespace mirror { } void destroyStray() { + if(geometry == gQuotient2) return; for(int i=0; icpdist > 7 && isMimic(c)) { diff --git a/game.cpp b/game.cpp index 64b7bd8c..eaaaaee7 100644 --- a/game.cpp +++ b/game.cpp @@ -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) { diff --git a/hyper.h b/hyper.h index a0f3d2bd..d55abdb6 100644 --- a/hyper.h +++ b/hyper.h @@ -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; + diff --git a/hyper.rc b/hyper.rc index 881fe7fa..d8dd22fb 100644 --- a/hyper.rc +++ b/hyper.rc @@ -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 diff --git a/hyperpoint.cpp b/hyperpoint.cpp index 806ce0ec..2210e43d 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -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; diff --git a/init.cpp b/init.cpp index 0da83e1b..66456945 100644 --- a/init.cpp +++ b/init.cpp @@ -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 diff --git a/landgen.cpp b/landgen.cpp index e2488fc2..d8acc98d 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -5691,8 +5691,7 @@ namespace halloween { cell *farempty(bool lastresort = false) { int maxdist = 0; - cell* validcells[100]; - int qvc = 0; + vector validcells; int firstfar1 = 0; for(int i=1; iwall != 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)]; diff --git a/language-cz.cpp b/language-cz.cpp index 84b8900e..cc62be91 100644 --- a/language-cz.cpp +++ b/language-cz.cpp @@ -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 diff --git a/language-pl.cpp b/language-pl.cpp index 5ac443fc..3b39fac4 100644 --- a/language-pl.cpp +++ b/language-pl.cpp @@ -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 diff --git a/language-ru.cpp b/language-ru.cpp index 9fe7d1ba..4fa208a6 100644 --- a/language-ru.cpp +++ b/language-ru.cpp @@ -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 diff --git a/language.cpp b/language.cpp index 8cb5106f..55b8c74c 100644 --- a/language.cpp +++ b/language.cpp @@ -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", "ją", "je")); + rep(x, "%aka"+w, choose3(N->n[0].genus, "a", "ka", "a")); } else { rep(x,"%"+w, p.v); diff --git a/mapeditor.cpp b/mapeditor.cpp index ee79901b..f752a84b 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -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} }; diff --git a/menus.cpp b/menus.cpp index dcee2c0b..8e0bd55c 100644 --- a/menus.cpp +++ b/menus.cpp @@ -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; diff --git a/shmup.cpp b/shmup.cpp index 1aaa054c..b07de5a5 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -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 monstersAt; typedef multimap::iterator mit; -vector active; +vector 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; inotpushed = 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; itype == 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; jisVirtual) 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(disVirtual) { hyperpoint H = hornpos(cpid); - for(int j=0; jpat*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; jpat*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; itype)) - 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; jdead) 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; ibase->type; i++) + if(!quotient) for(int i=0; ibase->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; jisVirtual) 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; pidisVirtual) { 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; jtype != 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; pidisVirtual) continue; + if(m->isVirtual) continue; bool okay = intval(pc[pid]->pat*C0, m->pat*C0) < 2 * SCALE2; - for(int i=0; itype) && 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 bugtargets; - for(int i=0; itype != 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; itrackroute(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; ipat*C0, pc[i]->pat*C0) < SCALE2 * 2) { + if(m->type == moVampire && !m->isVirtual) for(int i=0; iisVirtual && intval(m->pat*C0, pc[i]->pat*C0) < SCALE2 * 2) { for(int i=0; iisVirtual) 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; jtype != 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; ifindbase(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; ipat*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; iisVirtual) 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; iisVirtual) 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; iisVirtual) 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 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::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) { - cell *c = it->first; - pair 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::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; ifindpat(); + if(m->isVirtual) continue; + else nonvirtual.push_back(m); exists[movegroup(m->type)] = true; } - for(int i=0; itype) { case moPlayer: @@ -2710,8 +2770,7 @@ void turn(int delta) { } } - for(int i=0; itype)) moveMimic(m); } @@ -2751,9 +2810,9 @@ void turn(int delta) { // move monsters of this type - for(int i=0; itype) == 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; idead && active[i]->type != moPlayer) { - for(int j=0; jparent == 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; ibase == 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