diff --git a/LICENSE b/COPYING similarity index 94% rename from LICENSE rename to COPYING index 8cdb8451..d60c31a9 100644 --- a/LICENSE +++ b/COPYING @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to +the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -290,8 +290,8 @@ to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - {description} - Copyright (C) {year} {fullname} + + Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -303,16 +303,17 @@ the "copyright" line and a pointer to where the full notice is found. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -329,12 +330,11 @@ necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. - {signature of Ty Coon}, 1 April 1989 + , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General +library. If this is what you want to do, use the GNU Library General Public License instead of this License. - diff --git a/DejaVuSans-Bold.ttf b/DejaVuSans-Bold.ttf new file mode 100644 index 00000000..08695f23 Binary files /dev/null and b/DejaVuSans-Bold.ttf differ diff --git a/LICENSE-ogg-vorbis.txt b/LICENSE-ogg-vorbis.txt new file mode 100644 index 00000000..429b0591 --- /dev/null +++ b/LICENSE-ogg-vorbis.txt @@ -0,0 +1,32 @@ +The source code to this library used with SDL_mixer can be found here: +http://www.libsdl.org/projects/SDL_mixer/libs/ +--- + +Copyright (c) 2002-2008 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSE-sdl.txt b/LICENSE-sdl.txt new file mode 100644 index 00000000..1669736c --- /dev/null +++ b/LICENSE-sdl.txt @@ -0,0 +1,13 @@ + +Please distribute this file with the SDL runtime environment: + +The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library +designed to make it easy to write multi-media software, such as games and +emulators. + +The Simple DirectMedia Layer library source code is available from: +http://www.libsdl.org/ + +This library is distributed under the terms of the GNU LGPL license: +http://www.gnu.org/copyleft/lesser.html + diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..74e64b1c --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CXXFLAGS ?= + +hyper: hyper.cpp graph.cpp hyperpoint.cpp geometry.cpp cell.cpp heptagon.cpp game.cpp classes.cpp polygons.cpp language.cpp language-data.cpp achievement.cpp + g++ hyper.cpp -o hyper -lSDL -lSDL_ttf -lSDL_mixer -DFHS -Wall -lSDL_gfx ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS} -lGL -O3 + +langen: langen.cpp language-cz.cpp language-pl.cpp language-tr.cpp language-ru.cpp + g++ langen.cpp -o langen + +language-data.cpp: langen + ./langen > language-data.cpp diff --git a/Makefile.mac b/Makefile.mac new file mode 100644 index 00000000..980a37f3 --- /dev/null +++ b/Makefile.mac @@ -0,0 +1,7 @@ +# note: this Makefile for Mac is based on this post. I have no resources to test it myself. +# http://groups.google.com/group/rec.games.roguelike.development/browse_thread/thread/9c02e09c0195dc16/3cbde3dc4a0b7e4e +# +# You will also probably need to configure it yourself a bit to make it work. + +hyper: hyper.cpp graph.cpp hyperpoint.cpp geometry.cpp cell.cpp heptagon.cpp game.cpp polygons.cpp classes.cpp + g++ -m32 -I/sw/include hyper.cpp -L/sw/lib -lSDL -lSDLMain -lSDL_ttf -lSDL_gfx -framework AppKit -DMAC -O3 diff --git a/Makefile.mgw b/Makefile.mgw new file mode 100644 index 00000000..aa76f970 --- /dev/null +++ b/Makefile.mgw @@ -0,0 +1,11 @@ +hyper.exe: hyper.cpp graph.cpp hyperpoint.cpp geometry.cpp cell.cpp heptagon.cpp game.cpp polygons.cpp classes.cpp hyper.res language-data.cpp + g++ -mwindows hyper.cpp hyper.res -o hyper.exe -lSDL -lSDL_mixer -lopengl32 SDL_ttf.dll SDL_gfx.dll -O3 + +hyper.res: hyper.rc hr-icon.ico + windres hyper.rc -O coff -o hyper.res + +langen.exe: langen.cpp language-cz.cpp language-pl.cpp language-tr.cpp language-ru.cpp + g++ langen.cpp -o langen.exe + +language-data.cpp: langen.exe + ./langen.exe > language-data.cpp diff --git a/SDL.dll b/SDL.dll new file mode 100644 index 00000000..a5da7bbd Binary files /dev/null and b/SDL.dll differ diff --git a/SDL_gfx.dll b/SDL_gfx.dll new file mode 100644 index 00000000..b202a1b7 Binary files /dev/null and b/SDL_gfx.dll differ diff --git a/SDL_mixer.dll b/SDL_mixer.dll new file mode 100644 index 00000000..89def763 Binary files /dev/null and b/SDL_mixer.dll differ diff --git a/SDL_ttf.dll b/SDL_ttf.dll new file mode 100644 index 00000000..0345453a Binary files /dev/null and b/SDL_ttf.dll differ diff --git a/achievement.cpp b/achievement.cpp new file mode 100644 index 00000000..7cf87e59 --- /dev/null +++ b/achievement.cpp @@ -0,0 +1,323 @@ +#define NUMLEADER 26 + +#define SCORE_UNKNOWN (-1) +#define NO_SCORE_YET (-2) + +int currentscore[NUMLEADER]; + +const char* leadernames[NUMLEADER] = { + "Score", "Diamonds", "Gold", "Spice", "Rubies", "Elixirs", + "Shards", "Totems", "Daisies", "Statues", "Feathers", "Sapphires", + "Hyperstones", "Time to Win", "Turns to Win", + "Time to 10 Hyperstones-62", "Turns to 10 Hyperstones-62", "Orbs of Yendor", + "Fern Flowers", + "Royal Jellies", "Powerstones", "Silver", "Wine", "Emeralds", "Grimoires", + "Holy Grails" + }; + +bool haveLeaderboard(int id); + +void upload_score(int id, int v); + +string achievementMessage[3]; +int achievementTimer; +// vector achievementsReceived; + +void achievement_log(const char* s, bool euclideanAchievement) { + if(cheater) return; + if(euclid != euclideanAchievement) return; + + for(int i=0; i= 5) + achievement_gain("GOLEM2"); + if(s == "GOLEM" && current >= 10) + achievement_gain("GOLEM3"); + if(s == "STAB" && current >= 1) + achievement_gain("STABBER1"); + if(s == "STAB" && current >= 2) + achievement_gain("STABBER2"); + if(s == "STAB" && current >= 4) + achievement_gain("STABBER3"); + if(s == "MIRRORKILL" && current-prev >= 1) + achievement_gain("MIRRORKILL1"); + if(s == "MIRRORKILL" && current-prev >= 2) + achievement_gain("MIRRORKILL2"); + if(s == "MIRRORKILL" && current-prev >= 3) + achievement_gain("MIRRORKILL3"); + if(s == "FLASH" && current-prev >= 1) + achievement_gain("FLASH1"); + if(s == "FLASH" && current-prev >= 5) + achievement_gain("FLASH2"); + if(s == "FLASH" && current-prev >= 10) + achievement_gain("FLASH3"); + if(s == "LIGHTNING" && current-prev >= 1) + achievement_gain("LIGHTNING1"); + if(s == "LIGHTNING" && current-prev >= 5) + achievement_gain("LIGHTNING2"); + if(s == "LIGHTNING" && current-prev >= 10) + achievement_gain("LIGHTNING3"); + if(s == "MIRAGE" && current >= 35) + achievement_gain("MIRAGE", true); + if(s == "ORB" && current >= 10) + achievement_gain("ORB3"); + if(s == "BUG" && current >= 1000) + achievement_gain("BUG3"); + } + +int specific_improved = 0; +int specific_what = 0; + +void improve_score(int i, eItem what) { +#ifdef HAVE_ACHIEVEMENTS + if(items[what] && haveLeaderboard(i)) { + if(items[what] > currentscore[i] && currentscore[i] != SCORE_UNKNOWN) { + specific_improved++; specific_what = what; + currentscore[i] = items[what]; + } + + upload_score(i, items[what]); + } +#endif + } + +void achievement_final(bool really_final) { +#ifdef HAVE_ACHIEVEMENTS + if(cheater) return; + if(euclid) return; + int total_improved = 0; + specific_improved = 0; + specific_what = 0; + + for(int i=1; i<=12; i++) improve_score(i, eItem(i)); + improve_score(17, itOrbYendor); + improve_score(18, itFernFlower); + improve_score(19, itRoyalJelly); + improve_score(20, itPower); + improve_score(21, itSilver); + improve_score(22, itWine); + improve_score(23, itEmerald); + improve_score(24, itGrimoire); + improve_score(25, itHolyGrail); + + int tg = gold(); + if(tg && haveLeaderboard(0)) { + if(tg > currentscore[0] && currentscore[0] != SCORE_UNKNOWN) { + if(currentscore[0] < 0) total_improved += 2; + total_improved++; currentscore[0] = tg; + } + upload_score(0, tg); + } + + if(total_improved >= 2) { + addMessage(XLAT("Your total treasure has been recorded in the "LEADERFULL".")); + addMessage(XLAT("Congratulations!")); + } + else if(total_improved && specific_improved >= 2) + addMessage(XLAT("You have improved your total high score and %1 specific high scores!", its(specific_improved))); + else if(total_improved && specific_improved) + addMessage(XLAT("You have improved your total and '%1' high score!", iinf[specific_what].name)); + else if(total_improved) + addMessage(XLAT("You have improved your total high score on "LEADER". Congratulations!")); + else if(specific_improved >= 2) + addMessage(XLAT("You have improved %1 of your specific high scores!", its(specific_improved))); + else if(specific_improved) + addMessage(XLAT("You have improved your '%1' high score on "LEADER"!", iinf[specific_what].name)); +#endif + } + +void achievement_victory(bool hyper) { +#ifdef HAVE_ACHIEVEMENTS + if(cheater) return; + if(euclid) return; + + int t = savetime + time(NULL) - timerstart; + + int ih1 = hyper ? 15 : 13; + int ih2 = hyper ? 16 : 14; + + int improved = 0; + if(currentscore[ih1] == NO_SCORE_YET || currentscore[ih2] == NO_SCORE_YET) + improved += 4; + + if(currentscore[ih1] < 0 || currentscore[ih1] > t) { + improved++; currentscore[ih1] = t; + } + + if(currentscore[ih2] < 0 || currentscore[ih2] > turncount) { + improved+=2; currentscore[ih2] = turncount; + } + + if(hyper) + addMessage(XLAT("You have collected 10 treasures of each type.")); + + if(improved) { + if(improved >= 4) { + if(!hyper) addMessage(XLAT("This is your first victory!")); + addMessage(XLAT("This has been recorded in the " LEADERFULL ".")); + addMessage(XLAT("The faster you get here, the better you are!")); + } + else if(improved >= 3) + addMessage(XLAT("You have improved both your real time and turn count. Congratulations!")); + else if(improved == 1) + addMessage(XLAT("You have used less real time than ever before. Congratulations!")); + else if(improved == 2) + addMessage(XLAT("You have used less turns than ever before. Congratulations!")); + } + + upload_score(ih1, t); + upload_score(ih2, turncount); +#endif + } + +void achievement_pump(); + +void achievement_display() { +#ifdef HAVE_ACHIEVEMENTS + achievement_pump(); + if(achievementTimer) { + int col = (ticks - achievementTimer); + if(col > 5000) { achievementTimer = 0; return; } + if(col > 2500) col = 5000 - col; + col /= 10; col *= 0x10101; + displayfr(vid.xres/2, vid.yres/4, 2, vid.fsize * 2, achievementMessage[0], col & 0xFFFF00, 8); + displayfr(vid.xres/2, vid.yres/4 + vid.fsize*2, 2, vid.fsize * 2, achievementMessage[1], col, 8); + displayfr(vid.xres/2, vid.yres/4 + vid.fsize*4, 2, vid.fsize, achievementMessage[2], col, 8); + } +#endif + } + diff --git a/achievement.h b/achievement.h new file mode 100644 index 00000000..339a3cba --- /dev/null +++ b/achievement.h @@ -0,0 +1,30 @@ +// initialize the achievement system. +void achievement_init(); + +// close the achievement system. +void achievement_close(); + +// gain the achievement with the given name. +// Only awarded if euclid equals euclideanAchievement. +void achievement_gain(const char*, bool euclideanAchievement = false); + +// gain the achievement for collecting a number of 'it'. +void achievement_collection(eItem it, int prevgold, int newgold); + +// this is used for 'counting' achievements, such as kill 10 +// monsters at the same time. +void achievement_count(const string& s, int current, int prev); + +// gain the victory achievements. Set 'hyper' to true for +// the Hyperstone victory, and false for the Orb of Yendor victory. +void achievement_victory(bool hyper); + +// gain the final achievements. Called with really=false whenever the user +// looks at their score, and really=true when the game really ends. +void achievement_final(bool really); + +// display the last achievement gained. +void achievement_display(); + +// achievements received this game +vector achievementsReceived; diff --git a/cell.cpp b/cell.cpp new file mode 100644 index 00000000..0c5fa128 --- /dev/null +++ b/cell.cpp @@ -0,0 +1,375 @@ +// Hyperbolic Rogue +// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details + +// cells the game is played on + +int fix6(int a) { return (a+96)% 6; } + +struct cell : gcell { + char type; // 6 for hexagons, 7 for heptagons + unsigned char spn[7]; + heptagon *master; + cell *mov[7]; // meaning very similar to heptagon::move + }; + +int cellcount = 0; + +void initcell(cell *c); // from game.cpp + +cell *newCell(int type, heptagon *master) { + cell *c = new cell; + cellcount++; + c->type = type; + c->master = master; + for(int i=0; i<7; i++) c->mov[i] = NULL; + initcell(c); + return c; + } + +void merge(cell *c, int d, cell *c2, int d2) { + c->mov[d] = c2; + c->spn[d] = d2; + c2->mov[d2] = c; + c2->spn[d2] = d; + } + +typedef unsigned short eucoord; + +cell*& euclideanAtCreate(eucoord x, eucoord y); + +union heptacoder { + heptagon *h; + struct { eucoord x; eucoord y; } c; + }; + +void decodeMaster(heptagon *h, eucoord& x, eucoord& y) { + heptacoder u; + u.h = h; x = u.c.x; y = u.c.y; + } + +heptagon* encodeMaster(eucoord x, eucoord y) { + heptacoder u; + u.c.x = x; u.c.y = y; + return u.h; + } + +// very similar to createMove in heptagon.cpp +cell *createMov(cell *c, int d) { + + if(euclid && !c->mov[d]) { + eucoord x, y; + decodeMaster(c->master, x, y); + for(int dx=-1; dx<=1; dx++) + for(int dy=-1; dy<=1; dy++) + euclideanAtCreate(x+dx, y+dy); + if(!c->mov[d]) { printf("fail!\n"); } + } + + if(c->mov[d]) return c->mov[d]; + else if(c->type == 7) { + cell *n = newCell(6, c->master); + + c->mov[d] = n; n->mov[0] = c; + c->spn[d] = 0; n->spn[0] = d; + + heptspin hs; hs.h = c->master; hs.spin = d; + + heptspin hs2 = hsstep(hsspin(hs, 3), 3); + + // merge(hs2.h->c7, hs2.spin, n, 2); + + hs2.h->c7->mov[hs2.spin] = n; n->mov[2] = hs2.h->c7; + hs2.h->c7->spn[hs2.spin] = 2; n->spn[2] = hs2.spin; + + hs2 = hsstep(hsspin(hs, 4), 4); + // merge(hs2.h->c7, hs2.spin, n, 4); + hs2.h->c7->mov[hs2.spin] = n; n->mov[4] = hs2.h->c7; + hs2.h->c7->spn[hs2.spin] = 4; n->spn[4] = hs2.spin; + + } + + else if(d == 5) { + int di = fixrot(c->spn[0]+1); + cell *c2 = createMov(c->mov[0], di); + merge(c, 5, c2, fix6(c->mov[0]->spn[di] + 1)); + + // c->mov[5] = c->mov[0]->mov[fixrot(c->spn[0]+1)]; + // c->spn[5] = fix6(c->mov[0]->spn[fixrot(c->spn[0]+1)] + 1); + } + + else if(d == 1) { + int di = fixrot(c->spn[0]-1); + cell *c2 = createMov(c->mov[0], di); + merge(c, 1, c2, fix6(c->mov[0]->spn[di] - 1)); + + // c->mov[1] = c->mov[0]->mov[fixrot(c->spn[0]-1)]; + // c->spn[1] = fix6(c->mov[0]->spn[fixrot(c->spn[0]-1)] - 1); + } + + else if(d == 3) { + int di = fixrot(c->spn[2]-1); + cell *c2 = createMov(c->mov[2], di); + merge(c, 3, c2, fix6(c->mov[2]->spn[di] - 1)); + // c->mov[3] = c->mov[2]->mov[fixrot(c->spn[2]-1)]; + // c->spn[3] = fix6(c->mov[2]->spn[fixrot(c->spn[2]-1)] - 1); + } + return c->mov[d]; + } + +// similar to heptspin from heptagon.cpp +struct cellwalker { + cell *c; + int spin; + cellwalker(cell *c, int spin) : c(c), spin(spin) {} + cellwalker() {} + }; + +void cwspin(cellwalker& cw, int d) { + cw.spin = (cw.spin+d + 42) % cw.c->type; + } + +bool cwstepcreates(cellwalker& cw) { + return cw.c->mov[cw.spin] == NULL; + } + +void cwstep(cellwalker& cw) { + createMov(cw.c, cw.spin); + int nspin = cw.c->spn[cw.spin]; + cw.c = cw.c->mov[cw.spin]; + cw.spin = nspin; + } + +void eumerge(cell* c1, cell *c2, int s1, int s2) { + if(!c2) return; + c1->mov[s1] = c2; c1->spn[s1] = s2; + c2->mov[s2] = c1; c2->spn[s2] = s1; + } + +struct euclideanSlab { + cell* a[256][256]; + euclideanSlab() { + for(int y=0; y<256; y++) for(int x=0; x<256; x++) + a[y][x] = NULL; + } + ~euclideanSlab() { + for(int y=0; y<256; y++) for(int x=0; x<256; x++) + if(a[y][x]) delete a[y][x]; + } + }; + +euclideanSlab* euclidean[256][256]; + +// map, cell*> euclidean; + +cell*& euclideanAt(eucoord x, eucoord y) { + euclideanSlab*& slab(euclidean[y>>8][x>>8]); + if(!slab) slab = new euclideanSlab; + return slab->a[y&255][x&255]; + } + +cell*& euclideanAtCreate(eucoord x, eucoord y) { + cell*& c ( euclideanAt(x,y) ); + if(!c) { + c = newCell(6, &origin); + c->master = encodeMaster(x,y); + euclideanAt(x,y) = c; + eumerge(c, euclideanAt(x+1,y), 0, 3); + eumerge(c, euclideanAt(x,y+1), 1, 4); + eumerge(c, euclideanAt(x-1,y+1), 2, 5); + eumerge(c, euclideanAt(x-1,y), 3, 0); + eumerge(c, euclideanAt(x,y-1), 4, 1); + eumerge(c, euclideanAt(x+1,y-1), 5, 2); + } + return c; + } + + +// initializer (also inits origin from heptagon.cpp) +void initcells() { + + origin.s = hsOrigin; + origin.fjordval = 98; + for(int i=0; i<7; i++) origin.move[i] = NULL; + origin.alt = NULL; + origin.distance = 0; + if(euclid) + origin.c7 = euclideanAtCreate(0,0); + else + origin.c7 = newCell(7, &origin); + + // origin.fjordval = + } + +#define DEBMEM(x) // { x fflush(stdout); } + +void clearcell(cell *c) { + if(!c) return; + DEBMEM ( printf("c%d %p\n", c->type, c); ) + for(int t=0; ttype; t++) if(c->mov[t]) { + DEBMEM ( printf("mov %p [%p] S%d\n", c->mov[t], c->mov[t]->mov[c->spn[t]], c->spn[t]); ) + if(c->mov[t]->mov[c->spn[t]] != NULL && + c->mov[t]->mov[c->spn[t]] != c) { + printf("cell error\n"); + exit(1); + } + c->mov[t]->mov[c->spn[t]] = NULL; + } + DEBMEM ( printf("DEL %p\n", c); ) + delete c; + } + +heptagon deletion_marker; + +#include +void clearfrom(heptagon *at) { + queue q; + q.push(at); + at->alt = &deletion_marker; +//int maxq = 0; + while(!q.empty()) { + at = q.front(); +// if(q.size() > maxq) maxq = q.size(); + q.pop(); + DEBMEM ( printf("from %p\n", at); ) + for(int i=0; i<7; i++) if(at->move[i]) { + if(at->move[i]->alt != &deletion_marker) + q.push(at->move[i]); + at->move[i]->alt = &deletion_marker; + DEBMEM ( printf("!mov %p [%p]\n", at->move[i], at->move[i]->move[at->spin[i]]); ) + if(at->move[i]->move[at->spin[i]] != NULL && + at->move[i]->move[at->spin[i]] != at) { + printf("hept error\n"); + exit(1); + } + at->move[i]->move[at->spin[i]] = NULL; + at->move[i] = NULL; + } + DEBMEM ( printf("at %p\n", at); ) + if(at->c7) { + for(int i=0; i<7; i++) + clearcell(at->c7->mov[i]); + clearcell(at->c7); + } + DEBMEM ( printf("!DEL %p\n", at); ) + if(at != &origin) delete at; + } +//printf("maxq = %d\n", maxq); + } + +void verifycell(cell *c) { + int t = c->type; + for(int i=0; imov[i]; + if(c2) { + if(t == 7) verifycell(c2); + if(c2->mov[c->spn[i]] && c2->mov[c->spn[i]] != c) + printf("cell error %p %p\n", c, c2); + } + } + } + +void verifycells(heptagon *at) { + for(int i=0; i<7; i++) if(at->move[i] && at->spin[i] == 0 && at->move[i] != &origin) + verifycells(at->move[i]); + for(int i=0; i<7; i++) if(at->move[i] && at->move[i]->move[at->spin[i]] && at->move[i]->move[at->spin[i]] != at) { + printf("hexmix error %p %p %p\n", at, at->move[i], at->move[i]->move[at->spin[i]]); + } + verifycell(at->c7); + } + +bool ishept(cell *c) { + // EUCLIDEAN + if(euclid) { + eucoord x, y; + decodeMaster(c->master, x, y); + return (short(y+2*x))%3 == 0; + } + else return c->type == 7; + } + +void clearMemory() { + extern void clearGameMemory(); + clearGameMemory(); + // EUCLIDEAN + if(euclid) { + for(int y=0; y<256; y++) for(int x=0; x<256; x++) + if(euclidean[y][x]) { + delete euclidean[y][x]; + euclidean[y][x] = NULL; + } + } + else { + DEBMEM ( verifycells(&origin); ) + clearfrom(&origin); + for(int i=0; itype == 7) + return c->master->fjordval >> 3; + else { + return fjord_hexagon( + fjordval(createMov(c,0)), + fjordval(createMov(c,2)), + fjordval(createMov(c,4)) + ); + } + } + +int eudist(short sx, short sy) { + int z0 = abs(sx); + int z1 = abs(sy); + int z2 = abs(sx+sy); + return max(max(z0,z1), z2); + } + +int celldist(cell *c) { + if(euclid) { + eucoord x, y; + decodeMaster(c->master, x, y); + return eudist(x, y); + } + if(c->type == 7) return c->master->distance; + int dx[3]; + for(int u=0; u<3; u++) + dx[u] = createMov(c, u+u)->master->distance; + int mi = min(min(dx[0], dx[1]), dx[2]); + if(dx[0] > mi+2 || dx[1] > mi+2 || dx[2] > mi+2) + return -1; // { printf("cycle error!\n"); exit(1); } + if(dx[0] == mi+2 || dx[1] == mi+2 || dx[2] == mi+2) + return mi+1; + return mi; + } + +#define ALTDIST_BOUNDARY 99999 +#define ALTDIST_UNKNOWN 99998 + +// defined in 'game' +int euclidAlt(short x, short y); + +int celldistAlt(cell *c) { + if(euclid) { + eucoord x, y; + decodeMaster(c->master, x, y); + return euclidAlt(x, y); + } + if(c->type == 7) return c->master->alt->distance; + int dx[3]; + for(int u=0; u<3; u++) if(createMov(c, u+u)->master->alt == NULL) + return ALTDIST_UNKNOWN; + for(int u=0; u<3; u++) + dx[u] = createMov(c, u+u)->master->alt->distance; + int mi = min(min(dx[0], dx[1]), dx[2]); + if(dx[0] > mi+2 || dx[1] > mi+2 || dx[2] > mi+2) + return ALTDIST_BOUNDARY; // { printf("cycle error!\n"); exit(1); } + if(dx[0] == mi+2 || dx[1] == mi+2 || dx[2] == mi+2) + return mi+1; + return mi; + } + +#define GRAIL_FOUND 0x4000 +#define GRAIL_RADIUS_MASK 0x3FFF diff --git a/classes.cpp b/classes.cpp new file mode 100644 index 00000000..2b871aee --- /dev/null +++ b/classes.cpp @@ -0,0 +1,696 @@ +// --- help --- + +#define MC +#define M + +const char *wormdes = +MC"These huge monsters normally live below the sand, but your movements have " +MC"disturbed them. They are too big to be slain with your " +MC"weapons, but you can defeat them by making them unable to move. " +M "This also produces some Spice. They move two times slower than you."; + +const char *cocytushelp = +M "This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls."; + +const char *tentdes = +MC"The tentacles of Cthulhu are like sandworms, but longer. " +M "They also withdraw one cell at a time, instead of exploding instantly."; + +const char *gameboardhelp = +MC"Ever wondered how some boardgame would look on the hyperbolic plane? " +MC"I wondered about Go, so I have created this feature. Now you can try yourself!\n" +MC"Enter = pick up an item (and score), space = clear an item\n" +M "Other keys place orbs and terrain features of various kinds\n" + "In the periodic editor, press 0-4 to switch walls in different ways\n" + ; + +const char *ivydes = +MC"A huge plant growing in the Jungle. Each Ivy has many branches, " +MC"and one branch grows per each of your moves. Branches grow in a clockwise " +M "order. The root itself is vulnerable."; + +const char *slimehelp = +MC"The Alchemists produce magical potions from pools of blue and red slime. You " +MC"can go through these pools, but you cannot move from a blue pool to a red " +MC"pool, or vice versa. Pools containing items count as colorless, and " +MC"they change color to the PC's previous color when the item is picked up. " +MC"Slime beasts also have to keep to their own color, " +MC"but when they are killed, they explode, destroying items and changing " +M "the color of the slime and slime beasts around them."; + +const char *gdemonhelp = +MC "These creatures are slow, but very powerful... more powerful than you. " +MC "You need some more experience in demon fighting before you will be able to defeat them. " +MC "Even then, you will be able to slay this one, but more powerful demons will come...\n\n" +MC "Each 10 lesser demons you kill, you become powerful enough to kill all the greater " +M "demons on the screen, effectively turning them into lesser demons."; + +const char *ldemonhelp = +M "These creatures are slow, but they often appear in large numbers."; + +const char *trollhelp = +MC"A big monster from the Living Caves. A dead Troll will be reunited " +M "with the rocks, causing some walls to grow around its body."; + +const char *camelothelp = + "The Knights of the Round Table are the greatest warriors of these lands. " + "They are not very inventive with names though, as they call each of their " + "castles Camelot. " + "You are probably worth of joining them, but they will surely give you " + "some quest to prove yourself...\n\n" + "Each castle contains a single treasure, the Holy Grail, in the center. " + "The radius of the Round Table is usually 28, but after you find a Holy Grail " + "successfully, each new castle (and each Round Table) you find will be bigger."; + +const char *templehelp = + "The temple of Cthulhu consists of many concentric circles of columns. " + "You will surely encounter many Cultists there, who believe that a pilgrimage " + "to the inner circles will bring them closer to Cthulhu himself, and Grimoires " + "which surely contain many interesting secrets.\n\n" + "The circles in the temple of Cthulhu are actually horocycles. They are " + "infinite, and there is an infinite number of them."; + +const char *barrierhelp = +M "Huge, impassable walls which separate various lands."; + +const char *cavehelp = +MC"This cave contains walls which are somehow living. After each turn, each cell " +MC"counts the number of living wall and living floor cells around it, and if it is " +MC"currently of a different type than the majority of cells around it, it switches. " +MC"Items count as three floor cells, and dead Trolls count as five wall cells. " +M "Some foreign monsters also count as floor or wall cells.\n"; + +const char *vinehelp = + "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n" + "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa."; + +const char *hvinehelp = + "A vine is growing here... but only on a half of the cell. How is that even possible?!" + "Most monsters cannot move from this cell to the cell containing the other half. " + "Vine spirits can move only to the adjacent cells which are also adjacent to the " + "other half."; + +const char *deadcavehelp = + "Somehow, this cave has not received the spark of Life yet."; + +const char *foresthelp = +MC"This forest is quite dry. Beware the bushfires!\n" +MC"Trees catch fire on the next turn. The temperature of the grass cells " +MC"rises once per turn for each fire nearby, and becomes fire itself " +MC"when its temperature has risen 10 times.\n" +M "You can also cut down the trees. Big trees take two turns to cut down."; + +const char *hivehelp = + "The Hive is filled with Hyperbugs. They are huge insects which look a bit like " + "ants, a bit like bees, and a bit like roaches. " + "They live in circular nests, and an army of Hyperbugs will attack any intruder, " + "including you and enemy Hyperbugs. Will you manage to get to the " + "heart of such a nest, and get the precious Royal Jelly?"; + +// --- monsters --- + +const int motypes = 67; + +struct monstertype { + char glyph; + int color; + const char *name; + const char *help; + }; + +#define BUGCOLORS 3 + +monstertype minf[motypes] = { + { 0, 0, "none" , NULL}, + { 'Y', 0x4040FF, "Yeti" , +M "A big and quite intelligent monster living in the Icy Land." + }, + { 'W', 0xD08040, "Icewolf" , +MC "A nasty predator from the Icy Land. Contrary to other monsters, " +M "it tracks its prey by their heat." + }, + { 'W', 0xD08040, "Icewolf" , ""}, + { 'R', 0xFF8000, "Ranger" , +MC "Rangers take care of the magic mirrors in the Land of Mirrors. " +MC "They know that rogues like to break these mirrors... so " +M "they will attack you!" + }, + { 'T', 0xD0D0D0, "Rock Troll", trollhelp}, + { 'G', 0x20D020, "Goblin", +MC "A nasty creature native to the Living Caves. They don't like you " +M "for some reason." + }, + { 'S', 0xE0E040, "Sand Worm", wormdes }, + { 's', 0x808000, "Sand Worm Tail", wormdes }, + { 'S', 0x808000, "Sand Worm W", wormdes }, + { 'H', 0x80FF00, "Hedgehog Warrior", +MC "These warriors of the Forest wield exotic weapons called hedgehog blades. " +MC "These blades protect them from a frontal attack, but they still can be 'stabbed' " +M "easily by moving from one place next to them to another." + }, + { 'M', 0x806050, "Desert Man", +M "A tribe of men native to the Desert. They have even tamed the huge Sandworms, who won't attack them."}, + { 'C', 0x00FFFF, "Ivy Root", ivydes}, + { 'C', 0xFFFF00, "Active Ivy", ivydes}, + { 'C', 0x40FF00, "Ivy Branch", ivydes}, + { 'C', 0x006030, "Dormant Ivy", ivydes}, + { 'C', 0x800000, "Ivy N", ivydes}, + { 'C', 0x800000, "Ivy D", ivydes}, + { 'M', 0x804000, "Giant Ape", +M "This giant ape thinks that you are an enemy."}, + { 'B', 0x909000, "Slime Beast", slimehelp}, + { '@', 0x8080FF, "Mirror Image", +M "A magical being which copies your movements." + }, + { '@', 0xFF8080, "Mirage", +MC "A magical being which copies your movements. " +M "You feel that it would be much more useful in an Euclidean space." + }, + { '@', 0x509050, "Golem", +M "You can summon these friendly constructs with a magical process." + }, + { '@', 0x509050, "Golem", +M "You can summon these friendly constructs with a magical process." + }, + { 'E', 0xD09050, "Eagle", +M "A majestic bird, who is able to fly very fast." + }, + { 'S', 0xFF8080, "Seep", +M "A monster who is able to live inside the living cave wall." + }, + { 'Z', 0x804000, "Zombie", +M "A typical Graveyard monster." + }, + { 'G', 0xFFFFFF, "Ghost", +M "A typical monster from the Graveyard, who moves through walls.\n\n" + "There are also wandering Ghosts. They will appear " + "if you do not explore any new places for a long time (about 100 turns). " + "They can appear anywhere in the game." + }, + { 'N', 0x404040, "Necromancer", +M "Necromancers can raise ghosts and zombies from fresh graves." + }, + { 'S', 0x404040, "Shadow", +M "A creepy monster who follows you everywhere in the Graveyard." + }, + { 'T', 0x40E040, "Tentacle", tentdes }, + { 't', 0x008000, "Tentacle Tail", tentdes }, + { 'T', 0x008000, "Tentacle W", tentdes }, + { 'z', 0xC00000, "Tentacle (withdrawing)", tentdes }, + { 'P', 0xFF8000, "Cultist", +M "People worshipping Cthulhu. They are very dangerous." + }, + { 'P', 0xFFFF00, "Fire Cultist", +MC "People worshipping Cthulhu. This one is especially dangerous, " +M "as he is armed with a weapon which launches fire from afar." + }, + { 'D', 0xFF0000, "Greater Demon", gdemonhelp}, + { 'D', 0x800000, "Greater Demon", gdemonhelp}, + { 'd', 0xFF2020, "Lesser Demon", ldemonhelp}, + { 'd', 0x802020, "Lesser Demon", ldemonhelp}, + { 'S', 0x2070C0, "Ice Shark", +M "This dangerous predator has killed many people, and has been sent to Cocytus." + }, + { 'W', 0xFFFFFF, "Running Dog", +MC "This white dog is able to run all the time. It is the only creature " +M "able to survive and breed in the Land of Eternal Motion." + }, + { 'S', 0xC00040, "Demon Shark", +MC "Demons of Hell do not drown when they fall into the lake in Cocytus. " +M "They turn into demonic sharks, enveloped in a cloud of steam." + }, + { 'S', 0xC00040, "Fire Fairy", +MC "These fairies would rather burn the forest, than let you get some Fern Flowers. " +MC "The forest is infinite, after all...\n\n" +M "Fire Fairies transform into fires when they die." + }, + { 'C', 0x4000C0, "Crystal Sage", +MC "This being radiates an aura of wisdom. " +MC "It is made of a beautiful crystal, you would love to take it home. " +MC "But how is it going to defend itself? Better not to think of it, " +MC "thinking causes your brain to go hot...\n\n" +M "Crystal Sages melt at -30 °C, and they can rise the temperature around you from afar." + }, + { 'P', 0x4040C0, "Pikeman", + "When Pikemen move, they attack all cells which are now adjacent to them. " + "Luckily, they can be killed in the same way.\n\n" + "They never move if this would attack their friends." + }, + { 'F', 0xC04040, "Flail Guard", + "This guard of the Emerald Mine is wielding a huge flail. " + "You cannot attack him directly, as the flail would still hit you then. " + "Luckily, you have learned a trick: if you step away from him, " + "he will hit himself with the flail!" + }, + { 'M', 0x404040, "Miner", + "Miners have special tools for dealing with the Living Cave. " + "When they die, these tools activate, destroying the living cave " + "around them." + }, + { 'V', 0x421C52, "Vine Beast", + "A beast made of vines!\n\n" + "Vine Beasts turn into vines when they die." + }, + { 'V', 0x003000, "Vine Spirit", + "A spirit living in the vines!\n\n" + "Vine Spirits destroy the vines when they die." + }, + { 'T', 0x803030, "Dark Troll", + "A Troll without the power of Life." + }, + { 'E', 0xFFFF40, "Earth Elemental", + "A rare unliving construct from the Dead Caves. " + "It instantly destroys cave walls next to its path, and also leaves " + "an impassable wall behind it. You suppose that this impassable wall helps it to " + "escape from some threats. You hope you won't meet these threats..." + }, + { 'B', 0xC04040, "Red Hyperbug", hivehelp}, + { 'B', 0x40C040, "Green Hyperbug", hivehelp}, + { 'B', 0x4040C0, "Blue Hyperbug", hivehelp}, + { 'W', 0x404040, "Witch Apprentice", + "A Witch without any special powers. But watch out! She will " + "pick up any basic Orbs on her path, and use their powers." + }, + { 'W', 0xFF4040, "Speed Witch", + "A Witch with a Speed spell. She moves twice as fast as you. Unless you " + "have an Orb of Speed too, of course!" + }, + { 'W', 0xFFFFFF, "Flash Witch", + "A Witch with a Flash spell. Very dangerous!\n\n" + "Luckily, she never uses the spell if it would kill her friends. " + "She could destroy an Evil Golem, though." + }, + { 'W', 0xFF8000, "Fire Witch", + "A Witch with a Fire spell. She will leave a trail of fire behind her." + }, + { 'W', 0x8080FF, "Winter Witch", + "A Witch with a Winter spell. She is able to move through fire." + }, + { 'W', 0x808080, "Aether Witch", + "A Witch with an Aether spell. She is able to move through fire and walls." + }, + { '@', 0x905050, "Evil Golem", + "Somebody has summoned these evil constructs with a magical process." + }, + { '@', 0x8080FF, "Knight", camelothelp }, + { 'P', 0xD10000, "Cult Leader", + "These Cultists can push the statues, just like you." + }, + { 'B', 0x909000, "Slime Beast", slimehelp}, + { '@', 0x8080FF, "Knight", camelothelp }, // knight moved + { '@', 0x8B4513, "Illusion", + "Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends." + }, + }; + +enum eMonster { + moNone, + moYeti, moWolf, moWolfMoved, + moRanger, + moTroll, moGoblin, + moWorm, moWormtail, moWormwait, moHedge, + moDesertman, + moIvyRoot, moIvyHead, moIvyBranch, moIvyWait, moIvyNext, moIvyDead, + moMonkey, + moSlime, + moMirror, moMirage, moGolem, moGolemMoved, + moEagle, moSeep, + moZombie, moGhost, moNecromancer, moShadow, + moTentacle, moTentacletail, moTentaclewait, moTentacleEscaping, + moCultist, moPyroCultist, + moGreater, moGreaterM, moLesser, moLesserM, + moShark, moRunDog, moGreaterShark, moFireFairy, + moCrystalSage, moLancer, moFlailer, moMiner, + moVineBeast, moVineSpirit, moDarkTroll, moEarthElemental, + moBug0, moBug1, moBug2, + moWitch, moWitchSpeed, moWitchFlash, moWitchFire, moWitchWinter, moWitchGhost, + moEvilGolem, moKnight, moCultistLeader, moSlimeNextTurn, moKnightMoved, + moIllusion, + // temporary + moDeadBug, moLightningBolt + }; + +#define NUMWITCH 7 + +// --- items ---- + +const int ittypes = 40; + +struct itemtype { + char glyph; + int color; + const char *name; + const char *help; + }; + +itemtype iinf[ittypes] = { + { 0, 0, "none", NULL}, + { '*', 0xFFFFFF, "Ice Diamond", +M "Cold white gems, found in the Icy Land." + }, + { '$', 0xFFD700, "Gold", +MC "An expensive metal from the Living Caves. For some reason " +M "gold prevents the living walls from growing close to it." + }, + { ';', 0xFF4000, "Spice", +MC "A rare and expensive substance found in the Desert. " +M "It is believed to extend life and raise special psychic powers." + }, + { '*', 0xC00000, "Ruby", +M "A beautiful gem from the Jungle." + }, + { '!', 0xFFFF00, "Elixir of Life", +MC "A wonderful beverage, apparently obtained by mixing red and blue slime. You definitely feel more " +M "healthy after drinking it, but you still fell that one hit of a monster is enough to kill you."}, + { '%', 0xFF00FF, "Shard", +MC "A piece of a magic mirror, or a mirage cloud, that can be used for magical purposes. Only mirrors and clouds " +M "in the Land of Mirrors leave these."}, + { '/', 0xFF8000, "Necromancer's Totem", +M "These sinister totems contain valuable gems."}, + { '%', 0x00D000, "Demon Daisy", +M "These star-shaped flowers native to Hell are a valuable alchemical component."}, + { '/', 0x00FF00, "Statue of Cthulhu", +M "This statue is made of materials which cannot be found in your world."}, + { '*', 0xFF8000, "Phoenix Feather", +M "One of few things that does not cause the floor in the Land of Eternal Motion to collapse. Obviously they are quite valuable." + }, + { '*', 0x8080FF, "Ice Sapphire", +M "Cold blue gems, found in the Cocytus." + }, + { '*', 0xEEFF20, "Hyperstone", +M "These bright yellow gems can be found only by those who have mastered the Crossroads." + }, + { '[', 0x8080FF, "Key", +MC "That's all you need to unlock the Orb of Yendor! Well... as long as you are able to return to the Orb that this key unlocks...\n\n" +M "Each key unlocks only the Orb of Yendor which led you to it." + }, + { 'o', 0x306030, "Dead Orb", +MC "These orbs can be found in the Graveyard. You think that they were once powerful magical orbs, but by now, their " +M "power is long gone. No way to use them, you could as well simply drop them...\n\n" + }, + { 'o', 0xFF20FF, "Orb of Yendor", +MC "This wonderful Orb can only be collected by those who have truly mastered this hyperbolic universe, " +MC "as you need the right key to unlock it. Luckily, your psychic abilities will let you know " +M "where the key is after you touch the Orb." }, + { 'o', 0xFFFF00, "Orb of Storms", +M "This orb can be used to invoke the lightning spell, which causes lightning bolts to shoot from you in all directions."}, + { 'o', 0xFFFFFF, "Orb of Flash", +M "This orb can be used to invoke a flash spell, which destroys almost everything in radius of 2."}, + { 'o', 0x8080FF, "Orb of Winter", +M "This orb can be used to invoke a wall of ice. It also protects you from fires."}, + { 'o', 0xFF6060, "Orb of Speed", +M "This orb can be used to move faster for some time."}, + { 'o', 0x90B090, "Orb of Life", +M "This orb can be used to summon friendly golems. It is used instantly when you pick it up."}, + { 'o', 0x60D760, "Orb of Shielding", +M "This orb can protect you from damage."}, + { 'o', 0x606060, "Orb of Earth", +M "This orb lets you go through living walls. It also has powers in some of the other lands."}, + { 'o', 0x20FFFF, "Orb of Teleport", +MC "This orb lets you instantly move to another location on the map. Just click a location which " +M "is not next to you to teleport there. " + }, + { 'o', 0xA0FF40, "Orb of Safety", +MC "This orb lets you instantly move to a safe faraway location. Knowing the nature of this strange world, you doubt " +MC "that you will ever find the way back...\n\n" +MC "Your game will be saved if you quit the game while the Orb of Safety is still powered.\n\n" +M "Technical note: as it is virtually impossible to return, this Orb recycles memory used for the world so far (even if you do not use it to save the game). " + }, + { 'o', 0x40C000, "Orb of Thorns", +M "This orb allows attacking Hedgehog Warriors directly, as well as stabbing other monsters.\n" + }, + { '%', 0x0000FF, "Fern Flower", +M "This flower brings fortune to the person who finds it.\n" + }, + { '!', 0x900000, "Wine", +M "Wine grown under hyperbolic sun would be extremely prized in your home location." + }, + { 'o', 0x706070, "Orb of Aether", +M "This orb allows one to pass through all kinds of walls and chasms." + }, + { '$', 0xFFFFC0, "Silver", + "A precious metal from the Dead Caves." + }, + { 'o', 0x005050, "Orb of the Mind", + "This orb allows you to instantly kill a non-adjacent enemy by clicking it. " + "Each use drains 30 charges." + }, + { '!', 0xE2B227, "Royal Jelly", + "This is what Hyperbug Queens eat. Very tasty and healthy." + }, + { '*', 0x60C060, "Emerald", + "A precious green gem from the Emerald Mines." + }, + { 'o', 0x421C52, "Orb of Invisibility", + "When you have this Orb, most monsters won't see you, unless " + "you are standing still, attacking, or picking up items." + }, + { '*', 0xFFFF00, "Powerstone", + "A Stone from the Land of Power. You are not sure what it is exactly, but " + "as the Powerstones are kept in crystal cabinets, they are surely valuable." + }, + { 'o', 0xFF4000, "Orb of Fire", + "When you have this Orb, you will leave a trail of fire behind you." + }, + { '!', 0xFFFF00, "Holy Grail", camelothelp }, + { '?', 0x00FF00, "Grimoire", + "The Grimoires contain many secrets of the Great Old Ones. " + "Each new inner circle in the Temple of Cthulhu contains new Grimoires, with new secrets. " + "You hope to read them when you return home, and to learn many things. " + "The knowledge is valuable to you, but it is rather pointless to try to get " + "several copies of the same Grimoire..." + }, + { 'o', 0xFF8000, "Orb of the Dragon", + "This Orb allows you to throw fire, just like the Fire Cultists.\n\n" + "Each fire drains 5 charges. You are not allowed to throw fire into adjacent cells." + }, + { 'o', 0x8B4513, "Orb of Trickery", + "This Orb allows you to create illusions of yourself. Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.\n\n" + "Each illusion takes 5 charges to create, and one extra charge " + "per turn. You can also click your illusion to take it away, restoring 4 charges.\n\n" + "If you have both Orb of Teleport and Orb of Trickery, Illusion is cast " + "first -- you can then teleport on your Illusion to switch places with it." + }, + }; + +enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue, + itFeather, itSapphire, itHyperstone, itKey, + itGreenStone, itOrbYendor, + itOrbLightning, itOrbFlash, itOrbWinter, itOrbSpeed, itOrbLife, itOrbShield, itOrbDigging, + itOrbTeleport, itOrbSafety, + itOrbThorns, itFernFlower, + itWine, itOrbGhost, itSilver, itOrbPsi, + itRoyalJelly, itEmerald, itOrbInvis, itPower, itOrbFire, + itHolyGrail, itGrimoire, + itOrbDragon, itOrbIllusion + }; + +// --- wall types --- + +const int walltypes = 37; + +struct walltype { + char glyph; + int color; + const char *name; + const char *help; + }; + +const char *lakeDesc = "Hell has these lakes everywhere... They are shaped like evil stars, and filled with burning sulphur."; + +walltype winf[walltypes] = { + { '.', 0xFF00FF, "none", NULL}, + { '#', 0x8080FF, "ice wall", +M "Ice Walls melt after some time has passed." + }, + { '#', 0xC06000, "great wall", barrierhelp}, + { '+', 0x900030, "red slime", slimehelp }, + { '+', 0x300090, "blue slime", slimehelp }, + { '#', 0xA0D0A0, "living wall", cavehelp}, + { '.', 0x306060, "living floor",cavehelp}, + { '#', 0xD03030, "dead troll", trollhelp}, + { '#', 0xCDA98F, "sand dune", +M "A natural terrain feature of the Desert." + }, + { '%', 0xC0C0FF, "Magic Mirror", +M "You can go inside the Magic Mirror, and produce some mirror images to help you." + }, + { '%', 0xFFC0C0, "Cloud of Mirage", +MC "Tiny droplets of magical water. You see images of yourself inside them. " +M "Go inside the cloud, to make these images help you."}, + { '^', 0x8D694F, "Thumper", +M "A device that attracts sandworms and other enemies. You need to activate it."}, + { '^', 0x804000, "Bonfire", +M "A heap of wood that can be used to start a fire. Everything is already here, you just need to touch it to fire it." + }, + { '+', 0xC0C0C0, "ancient grave", +M "An ancient grave." + }, + { '+', 0xD0D080, "fresh grave", +M "A fresh grave. Necromancers like those." + }, + { '#', 0x00FFFF, "column", +M "A piece of architecture typical to R'Lyeh." + }, + { '=', 0xFFFF00, "lake of sulphur", lakeDesc }, + { '=', 0xFFFF00, "lake of sulphur", lakeDesc }, + { '=', 0x000080, "lake", +M "An impassable lake in Cocytus." + }, + { '_', 0x000080, "frozen lake", cocytushelp }, + { '>', 0x101010, "chasm", +M "It was a floor... until something walked on it." + }, + { '>', 0x101010, "chasmD", +M "It was a floor... until something walked on it." + }, + { '#', 0x60C000, "big tree", foresthelp}, + { '#', 0x006000, "tree", foresthelp}, + { '#', 0x421C52*2, "vine", vinehelp}, + { ':', 0x006000, "vine", hvinehelp}, + { ';', 0x006000, "vine", hvinehelp}, + { '^', 0x804000, "partial fire", "This cell is partially on fire."}, + { '#', 0xA07070, "dead wall", deadcavehelp}, + { '.', 0x401010, "dead floor",deadcavehelp}, + { '.', 0x905050, "rubble", "Dead floor, with some rubble."}, + { '#', 0xD0D010, "weird rock", + "A weirdly colored rock. Hyperentomologists claim that the " + "Hyperbug armies use these rocks to navigate back home after a victorious battle." + }, + { '#', 0x8080C0, "crystal cabinet", + "Witches use these crystal cabinets to protect Powerstones, as well as the more " + "expensive Orbs. They are partially protected from thieves: they are too strong " + "to be smashed by conventional attacks, and if you try to steal the item " + "using an Orb of Aether, your Aether power will be completely drained." + }, + { '#', 0xC0C0C0, "wall of Camelot", camelothelp }, + { '#', 0xA06000, "Round Table", camelothelp }, + { '=', 0x0000A0, "moat of Camelot", camelothelp}, + { '+', 0x606060, "big statue of Cthulhu", + "These statues of Cthulhu are too large to carry, and they don't look too " + "valuable anyway. Most monsters will never go through them... they probably have " + "their reasons. But you can go! When you move into the cell containing " + "a statue, you push the statue to the cell you left.\n" + } + }; + +enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCavefloor, waDeadTroll, waDune, + waMirror, waCloud, waThumper, waBonfire, waAncientGrave, waFreshGrave, waColumn, waSulphurC, waSulphur, + waLake, waFrozenLake, waChasm, waChasmD, waDryTree, waWetTree, + waVinePlant, waVineHalfA, waVineHalfB, waPartialFire, + waDeadwall, waDeadfloor, waDeadfloor2, waWaxWall, waGlass, waCamelot, waRoundTable, + waCamelotMoat, + waBigStatue, + // temporary walls for various purposes + waTemporary, waEarthD + }; + +// --- land types --- + +const int numLands = 20; +const int landtypes = numLands + 3; + +struct landtype { + int color; + const char *name; + const char *help; + }; + +landtype linf[landtypes] = { + { 0xFF00FF, "???" , ""}, + { 0xC06000, "Great Wall" , ""}, + { 0xFF0000, "Crossroads" , +MC "This land is a quick gateway to other lands. It is very easy to find other lands " +MC "from the Crossroads. Which means that you find monsters from most other lands here!\n\n" +MC "As long as you have found enough treasure in their native lands, you can " +MC "find magical items in the Crossroads. Mirror Land brings mirrors and clouds, " +MC "and other land types bring magical orbs.\n\n" +MC "A special treasure, Hyperstone, can be found on the Crossroads, but only " +MC "after you have found 10 of every other treasure." + }, + { 0xCDA98F, "Desert", +M "A hot land, full of sand dunes, mysterious Spice, and huge and dangerous sand worms." + }, + { 0x8080FF, "Icy Land", +MC "A very cold land, full of ice walls. Your mere presence will cause these ice walls to " +M "melt, even if you don't want it." + }, + { 0x306060, "Living Cave", cavehelp}, + { 0x00C000, "Jungle", +M "A land filled with huge ivy plants and dangerous animals." + }, + { 0x900090, "Alchemist Lab", slimehelp}, + { 0x704070, "Mirror Land", +M "A strange land which contains mirrors and mirages, protected by Mirror Rangers."}, + { 0x404070, "Graveyard", +MC "All the monsters you kill are carried to this strange land, and buried. " +M "Careless Rogues are also carried here..." + }, + { 0x00FF00, "R'Lyeh", +M "An ancient sunken city which can be reached only when the stars are right.\n\n" + "You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu." + }, + { 0xC00000, "Hell", +M "A land filled with demons and molten sulphur. Abandon all hope ye who enter here!" + }, + { 0x00FF00, "Cocytus", + cocytushelp + }, + { 0xFFFF00, "Land of Eternal Motion", +MC "A land where you cannot stop, because every piece of floor is extremely unstable. Only monsters who " +MC "can run forever are able to survive there, and only phoenix feathers are so light that they do not disturb " +M "the floor.\n" + }, + { 0x008000, "Dry Forest", foresthelp}, + { 0x0000C0, "Emerald Mine", + "Evil people are mining for emeralds in this living cave. " + "It does not grow naturally, but it is dug out in a regular " + "pattern, which is optimal according to the evil engineers." + }, + { 0x421C52, "Vineyard", foresthelp}, + { 0x104040, "Dead Cave", deadcavehelp}, + { 0x705020, "Hive", hivehelp}, + { 0xFFFF00, "Land of Power", + "The Land of Power is filled with everburning fire, magical Orbs, and guarded by " + "witches and golems. There are basic orbs lying everywhere, and more prized ones " + "are kept in crystal cabinets.\n\n" + "Witches are allowed to use all the powers of the " + "basic orbs against intruders. These powers never expire, but a Witch " + "can use only one power at a time (not counting Orbs of Life).\n\n" + "Witches and Golems don't pursue you into other Lands. Also, most Orb powers" + "are drained when you leave the Land of Power." + }, + { 0xD0D0D0, "Camelot", camelothelp }, + { 0xD000D0, "Temple of Cthulhu", templehelp }, + { 0xE08020, "Game Board", gameboardhelp} + }; + +enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle, laAlchemist, laMirror, laGraveyard, + laRlyeh, laHell, laCocytus, laMotion, laDryForest, laFjord, laWineyard, laDeadCaves, + laHive, laPower, laCamelot, laTemple, laGameBoard }; + +// cell information for the game + +struct gcell { + // 8 bits + eLand land : 5; + unsigned mondir : 3; + // 8 bits + eMonster monst : 7; + unsigned ligon : 1; + // 16 bits + eWall wall : 6; + eLand barleft : 5, barright : 5; + // 16 bits + eItem item : 6; + unsigned cpdist : 5, mpdist : 5; + // 14 bits + unsigned pathdist : 10, bardir : 4; + short tmp; + float heat; + }; + +#define NODIR 7 +#define NOBARRIERS 8 diff --git a/fjordgen.cpp b/fjordgen.cpp new file mode 100644 index 00000000..6b91de10 --- /dev/null +++ b/fjordgen.cpp @@ -0,0 +1,407 @@ +// rules for the fjordvalues of heptagons. +int fjord_heptagon(int parent, int dir) { + + // no fjordgen here + if(parent == 0) return 0; + + #define RULE(t1,s1,d,t2,s2) \ + if(parent == t1*8+s1 && dir == d) return t2*8+s2; + + RULE(8,0,3,12,4) + RULE(8,0,4,12,0) + RULE(8,0,5,42,0) + RULE(8,1,3,40,0) + RULE(8,1,4,12,4) + RULE(8,1,5,12,0) + RULE(8,2,3,34,0) + RULE(8,2,4,40,0) + RULE(8,2,5,12,4) + RULE(8,3,3,10,0) + RULE(8,3,4,34,0) + RULE(8,3,5,40,0) + RULE(8,4,3,32,0) + RULE(8,4,4,10,0) + RULE(8,4,5,34,0) + RULE(8,5,3,42,0) + RULE(8,5,4,32,0) + RULE(8,5,5,10,0) + RULE(8,6,3,12,0) + RULE(8,6,4,42,0) + RULE(8,6,5,32,0) + RULE(9,0,3,13,4) + RULE(9,0,4,13,0) + RULE(9,0,5,43,0) + RULE(9,1,3,41,0) + RULE(9,1,4,13,4) + RULE(9,1,5,13,0) + RULE(9,2,3,35,0) + RULE(9,2,4,41,0) + RULE(9,2,5,13,4) + RULE(9,3,3,11,0) + RULE(9,3,4,35,0) + RULE(9,3,5,41,0) + RULE(9,4,3,33,0) + RULE(9,4,4,11,0) + RULE(9,4,5,35,0) + RULE(9,5,3,43,0) + RULE(9,5,4,33,0) + RULE(9,5,5,11,0) + RULE(9,6,3,13,0) + RULE(9,6,4,43,0) + RULE(9,6,5,33,0) + RULE(10,0,3,14,4) + RULE(10,0,4,14,0) + RULE(10,0,5,40,3) + RULE(10,1,3,42,4) + RULE(10,1,4,14,4) + RULE(10,1,5,14,0) + RULE(10,2,3,32,1) + RULE(10,2,4,42,4) + RULE(10,2,5,14,4) + RULE(10,3,3,8,0) + RULE(10,3,4,32,1) + RULE(10,3,5,42,4) + RULE(10,4,3,34,6) + RULE(10,4,4,8,0) + RULE(10,4,5,32,1) + RULE(10,5,3,40,3) + RULE(10,5,4,34,6) + RULE(10,5,5,8,0) + RULE(10,6,3,14,0) + RULE(10,6,4,40,3) + RULE(10,6,5,34,6) + RULE(11,0,3,15,4) + RULE(11,0,4,15,0) + RULE(11,0,5,41,3) + RULE(11,1,3,43,4) + RULE(11,1,4,15,4) + RULE(11,1,5,15,0) + RULE(11,2,3,33,1) + RULE(11,2,4,43,4) + RULE(11,2,5,15,4) + RULE(11,3,3,9,0) + RULE(11,3,4,33,1) + RULE(11,3,5,43,4) + RULE(11,4,3,35,6) + RULE(11,4,4,9,0) + RULE(11,4,5,33,1) + RULE(11,5,3,41,3) + RULE(11,5,4,35,6) + RULE(11,5,5,9,0) + RULE(11,6,3,15,0) + RULE(11,6,4,41,3) + RULE(11,6,5,35,6) + RULE(12,0,3,8,4) + RULE(12,0,4,40,1) + RULE(12,0,5,14,2) + RULE(12,1,3,12,6) + RULE(12,1,4,8,4) + RULE(12,1,5,40,1) + RULE(12,2,0,14,2) + RULE(12,2,1,42,6) + RULE(12,2,2,8,3) + RULE(12,2,3,12,5) + RULE(12,2,4,12,6) + RULE(12,2,5,8,4) + RULE(12,2,6,40,1) + RULE(12,3,3,8,3) + RULE(12,3,4,12,5) + RULE(12,3,5,12,6) + RULE(12,4,3,42,6) + RULE(12,4,4,8,3) + RULE(12,4,5,12,5) + RULE(12,5,3,14,2) + RULE(12,5,4,42,6) + RULE(12,5,5,8,3) + RULE(12,6,3,40,1) + RULE(12,6,4,14,2) + RULE(12,6,5,42,6) + RULE(13,0,3,9,4) + RULE(13,0,4,41,1) + RULE(13,0,5,15,2) + RULE(13,1,3,13,6) + RULE(13,1,4,9,4) + RULE(13,1,5,41,1) + RULE(13,2,3,13,5) + RULE(13,2,4,13,6) + RULE(13,2,5,9,4) + RULE(13,3,3,9,3) + RULE(13,3,4,13,5) + RULE(13,3,5,13,6) + RULE(13,4,3,43,6) + RULE(13,4,4,9,3) + RULE(13,4,5,13,5) + RULE(13,5,3,15,2) + RULE(13,5,4,43,6) + RULE(13,5,5,9,3) + RULE(13,6,3,41,1) + RULE(13,6,4,15,2) + RULE(13,6,5,43,6) + RULE(14,0,3,10,4) + RULE(14,0,4,42,5) + RULE(14,0,5,12,2) + RULE(14,1,3,14,6) + RULE(14,1,4,10,4) + RULE(14,1,5,42,5) + RULE(14,2,0,12,2) + RULE(14,2,3,14,5) + RULE(14,2,4,14,6) + RULE(14,2,5,10,4) + RULE(14,3,3,10,3) + RULE(14,3,4,14,5) + RULE(14,3,5,14,6) + RULE(14,4,3,40,2) + RULE(14,4,4,10,3) + RULE(14,4,5,14,5) + RULE(14,5,3,12,2) + RULE(14,5,4,40,2) + RULE(14,5,5,10,3) + RULE(14,6,3,42,5) + RULE(14,6,4,12,2) + RULE(14,6,5,40,2) + RULE(15,0,3,11,4) + RULE(15,0,4,43,5) + RULE(15,0,5,13,2) + RULE(15,1,3,15,6) + RULE(15,1,4,11,4) + RULE(15,1,5,43,5) + RULE(15,2,3,15,5) + RULE(15,2,4,15,6) + RULE(15,2,5,11,4) + RULE(15,3,3,11,3) + RULE(15,3,4,15,5) + RULE(15,3,5,15,6) + RULE(15,4,3,41,2) + RULE(15,4,4,11,3) + RULE(15,4,5,15,5) + RULE(15,5,3,13,2) + RULE(15,5,4,41,2) + RULE(15,5,5,11,3) + RULE(15,6,3,43,5) + RULE(15,6,4,13,2) + RULE(15,6,5,41,2) + RULE(32,0,3,43,2) + RULE(32,0,4,33,3) + RULE(32,0,5,42,3) + RULE(32,1,3,33,5) + RULE(32,1,4,43,2) + RULE(32,1,5,33,3) + RULE(32,2,3,42,1) + RULE(32,2,4,33,5) + RULE(32,2,5,43,2) + RULE(32,3,3,8,1) + RULE(32,3,4,42,1) + RULE(32,3,5,33,5) + RULE(32,4,3,10,6) + RULE(32,4,4,8,1) + RULE(32,4,5,42,1) + RULE(32,5,3,42,3) + RULE(32,5,4,10,6) + RULE(32,5,5,8,1) + RULE(32,6,3,33,3) + RULE(32,6,4,42,3) + RULE(32,6,5,10,6) + RULE(33,0,3,42,2) + RULE(33,0,4,32,3) + RULE(33,0,5,43,3) + RULE(33,1,3,32,5) + RULE(33,1,4,42,2) + RULE(33,1,5,32,3) + RULE(33,2,3,43,1) + RULE(33,2,4,32,5) + RULE(33,2,5,42,2) + RULE(33,3,3,9,1) + RULE(33,3,4,43,1) + RULE(33,3,5,32,5) + RULE(33,4,3,11,6) + RULE(33,4,4,9,1) + RULE(33,4,5,43,1) + RULE(33,5,3,43,3) + RULE(33,5,4,11,6) + RULE(33,5,5,9,1) + RULE(33,6,3,32,3) + RULE(33,6,4,43,3) + RULE(33,6,5,11,6) + RULE(34,0,3,35,4) + RULE(34,0,4,41,5) + RULE(34,0,5,35,2) + RULE(34,1,3,40,4) + RULE(34,1,4,35,4) + RULE(34,1,5,41,5) + RULE(34,2,3,10,1) + RULE(34,2,4,40,4) + RULE(34,2,5,35,4) + RULE(34,3,3,8,6) + RULE(34,3,4,10,1) + RULE(34,3,5,40,4) + RULE(34,4,3,40,6) + RULE(34,4,4,8,6) + RULE(34,4,5,10,1) + RULE(34,5,3,35,2) + RULE(34,5,4,40,6) + RULE(34,5,5,8,6) + RULE(34,6,3,41,5) + RULE(34,6,4,35,2) + RULE(34,6,5,40,6) + RULE(35,0,3,34,4) + RULE(35,0,4,40,5) + RULE(35,0,5,34,2) + RULE(35,1,3,41,4) + RULE(35,1,4,34,4) + RULE(35,1,5,40,5) + RULE(35,2,3,11,1) + RULE(35,2,4,41,4) + RULE(35,2,5,34,4) + RULE(35,3,3,9,6) + RULE(35,3,4,11,1) + RULE(35,3,5,41,4) + RULE(35,4,3,41,6) + RULE(35,4,4,9,6) + RULE(35,4,5,11,1) + RULE(35,5,3,34,2) + RULE(35,5,4,41,6) + RULE(35,5,5,9,6) + RULE(35,6,3,40,5) + RULE(35,6,4,34,2) + RULE(35,6,5,41,6) + RULE(40,0,3,34,5) + RULE(40,0,4,10,2) + RULE(40,0,5,14,1) + RULE(40,1,3,35,3) + RULE(40,1,4,34,5) + RULE(40,1,5,10,2) + RULE(40,2,3,34,1) + RULE(40,2,4,35,3) + RULE(40,2,5,34,5) + RULE(40,3,3,8,5) + RULE(40,3,4,34,1) + RULE(40,3,5,35,3) + RULE(40,4,3,12,3) + RULE(40,4,4,8,5) + RULE(40,4,5,34,1) + RULE(40,5,3,14,1) + RULE(40,5,4,12,3) + RULE(40,5,5,8,5) + RULE(40,6,3,10,2) + RULE(40,6,4,14,1) + RULE(40,6,5,12,3) + RULE(41,0,3,35,5) + RULE(41,0,4,11,2) + RULE(41,0,5,15,1) + RULE(41,1,3,34,3) + RULE(41,1,4,35,5) + RULE(41,1,5,11,2) + RULE(41,2,3,35,1) + RULE(41,2,4,34,3) + RULE(41,2,5,35,5) + RULE(41,3,3,9,5) + RULE(41,3,4,35,1) + RULE(41,3,5,34,3) + RULE(41,4,3,13,3) + RULE(41,4,4,9,5) + RULE(41,4,5,35,1) + RULE(41,5,3,15,1) + RULE(41,5,4,13,3) + RULE(41,5,5,9,5) + RULE(41,6,3,11,2) + RULE(41,6,4,15,1) + RULE(41,6,5,13,3) + RULE(42,0,3,10,5) + RULE(42,0,4,32,2) + RULE(42,0,5,33,4) + RULE(42,1,3,14,3) + RULE(42,1,4,10,5) + RULE(42,1,5,32,2) + RULE(42,2,3,12,1) + RULE(42,2,4,14,3) + RULE(42,2,5,10,5) + RULE(42,3,3,8,2) + RULE(42,3,4,12,1) + RULE(42,3,5,14,3) + RULE(42,4,3,32,6) + RULE(42,4,4,8,2) + RULE(42,4,5,12,1) + RULE(42,5,3,33,4) + RULE(42,5,4,32,6) + RULE(42,5,5,8,2) + RULE(42,6,3,32,2) + RULE(42,6,4,33,4) + RULE(42,6,5,32,6) + RULE(43,0,3,11,5) + RULE(43,0,4,33,2) + RULE(43,0,5,32,4) + RULE(43,1,3,15,3) + RULE(43,1,4,11,5) + RULE(43,1,5,33,2) + RULE(43,2,3,13,1) + RULE(43,2,4,15,3) + RULE(43,2,5,11,5) + RULE(43,3,3,9,2) + RULE(43,3,4,13,1) + RULE(43,3,5,15,3) + RULE(43,4,3,33,6) + RULE(43,4,4,9,2) + RULE(43,4,5,13,1) + RULE(43,5,3,32,4) + RULE(43,5,4,33,6) + RULE(43,5,5,9,2) + RULE(43,6,3,33,2) + RULE(43,6,4,32,4) + RULE(43,6,5,33,6) + + printf("HEPTAGONAL RULE MISSING for (%d,%d)\n", parent,dir); + exit(1); + } + +// calculate the fjordvalue of a hexagonal cell, +// based on the fjordvalues of the neighbor heptacells. +int fjord_hexagon(int a, int b, int c) { + // pick the lexicographically smallest representation of the cycle + if(b <= a || c dcal; // queue for cpdist +vector pathq; // queue for pathdist + +vector pathqm; // list of monsters to move (pathq restriced to monsters) + +vector targets; // list of monster targets + +// monsters of specific types to move +vector worms, ivies, ghosts, golems, mirrors, mirrors2; + +vector temps; // temporary changes during bfs +vector tempval; // restore temps + +// a bit nicer way of DFS +vector reachedfrom; + +// additional direction information for BFS algorithms +// it remembers from where we have got to this location +// the opposite cell will be added to the queue first, +// which helps the AI +vector movesofgood[8]; + +int first7; // the position of the first monster at distance 7 in dcal + +cellwalker cwt; // player character position + +bool isIcyLand(cell *c) { + return c->land == laIce || c->land == laCocytus; + } + +void initcell(cell *c) { + c->mpdist = INFD; // minimum distance from the player, ever + c->cpdist = INFD; // current distance from the player + c->pathdist = INFD; // current distance from the player, along paths (used by yetis) + c->heat = 0; + c->wall = waNone; + c->item = itNone; + c->monst = moNone; + c->bardir = NODIR; + c->land = laNone; + c->tmp = -1; + c->ligon = 0; + lastexplore = turncount; + } + +// 0 = basic treasure, 1 = something else, 2 = power orb +#define IC_TREASURE 0 +#define IC_OTHER 1 +#define IC_ORB 2 +int itemclass(eItem i) { + if(i == 0) return -1; + if(i < itKey || i == itFernFlower || + i == itWine || i == itSilver || i == itEmerald || i == itRoyalJelly || i == itPower || + i == itGrimoire) + return IC_TREASURE; + if(i == itKey || i == itOrbYendor || i == itGreenStone || i == itHolyGrail) + return IC_OTHER; + return IC_ORB; + } + +int puregold() { + int i = items[itOrbYendor] * 50 + items[itHolyGrail] * 10; + for(int t=0; tland; + return treasureType(lastland); + } + +void countLocalTreasure() { + eItem i = localTreasureType(); + currentLocalTreasure = i ? items[i] : 0; + } + +bool hellUnlocked() { + int i = 0; + for(int t=0; t= 10) + i++; + return i >= 9; + } + +bool hyperstonesUnlocked() { + for(int t=1; t mg) + mg = items[i]; + return mg; + } + +int tkills() { + return + kills[moYeti] + kills[moWolf] + + kills[moRanger] + kills[moTroll] + kills[moGoblin] + + kills[moWorm] + kills[moDesertman] + kills[moIvyRoot] + + kills[moMonkey] + kills[moEagle] + kills[moSlime] + kills[moSeep] + + kills[moRunDog] + + kills[moCultist] + kills[moTentacle] + kills[moPyroCultist] + + kills[moLesser] + kills[moGreater] + + kills[moZombie] + kills[moGhost] + kills[moNecromancer] + + kills[moHedge] + kills[moFireFairy] + + kills[moCrystalSage] + kills[moShark] + kills[moGreaterShark] + + kills[moMiner] + kills[moFlailer] + kills[moLancer] + + kills[moVineSpirit] + kills[moVineBeast] + + kills[moBug0] + kills[moBug1] + kills[moBug2] + + kills[moDarkTroll] + kills[moEarthElemental] + + kills[moWitch] + kills[moEvilGolem] + kills[moWitchFlash] + kills[moWitchFire] + + kills[moWitchWinter] + kills[moWitchSpeed] + + kills[moCultistLeader]; + } + +bool passable(cell *w, cell *from, bool monster_passable, bool mirror_passable) { + if(w->wall == waFloorA && from && from->wall == waFloorB && !w->item && !from->item) + return false; + if(w->wall == waFloorB && from && from->wall == waFloorA && !w->item && !from->item) + return false; + if(w->wall == waMirror || w->wall == waCloud) return mirror_passable; + if((w->wall == waVineHalfA || w->wall == waVineHalfB) && from && from->wall == w->wall) + return false; + if(w->wall == waNone || w->wall == waFloorA || w->wall == waFloorB || + w->wall == waCavefloor || w->wall == waFrozenLake || w->wall == waVineHalfA || + w->wall == waVineHalfB || w->wall == waDeadfloor || w->wall == waDeadfloor2) { + if(w->monst) return monster_passable; + return true; + } + return false; + } + +bool cellUnstable(cell *c) { + return c->land == laMotion && c->wall == waNone; + } + +bool cellUnstableOrChasm(cell *c) { + return c->land == laMotion && (c->wall == waNone || c->wall == waChasm); + } + +bool cellHalfvine(cell *c) { + return c->wall == waVineHalfA || c->wall == waVineHalfB; + } + +bool thruVine(cell *c, cell *c2) { + return cellHalfvine(c) && c2->wall == c->wall; + } + +bool itemBurns(eItem it) { + return it && it != itOrbDragon && it != itOrbFire; + } + +bool attackThruVine(eMonster m) { + return m == moGhost || m == moVineSpirit; + } + +// target, source +bool attackingForbidden(cell *c, cell *c2) { + return thruVine(c, c2) && !attackThruVine(c2->monst) && !attackThruVine(c->monst); + } + +bool isFire(cell *w) { + return w->wall == waBonfire || w->wall == waPartialFire; + } + +// eagles can go through lakes, chasms, and slime +// todo vines? +bool eaglepassable(cell *w) { + if(w->monst) return false; + return + w->wall == waNone || w->wall == waFloorA || w->wall == waFloorB || + w->wall == waCavefloor || w->wall == waFrozenLake || w->wall == waLake || + w->wall == waDeadfloor || w->wall == waDeadfloor2 || w->wall == waCamelotMoat || + w->wall == waSulphur || w->wall == waSulphurC || w->wall == waChasm; + } + +bool isActiv(cell *c) { + return c->wall == waThumper || c->wall == waBonfire || c->wall == waPartialFire; + } + +bool isMimic(eMonster m) { + return m == moMirror || m == moMirage; + } + +bool isMimic(cell *c) { + return isMimic(c->monst); + } + +bool isGolemOrKnight(cell *c) { + return + c->monst == moGolem || c->monst == moGolemMoved || + c->monst == moKnight ||c->monst == moKnightMoved; + } + +bool isFriendly(cell *c) { + return isMimic(c->monst) || isGolemOrKnight(c) || c->monst == moIllusion; + } + +bool isBug(eMonster m) { + return m >= moBug0 && m < moBug0+BUGCOLORS; + } + +bool isBug(cell *c) { + return isBug(c->monst); + } + +bool isFriendlyOrBug(cell *c) { + return isFriendly(c) || isBug(c); + } + +bool isIvy(cell *c) { + return c->monst == moIvyRoot || c->monst == moIvyHead || c->monst == moIvyBranch || c->monst == moIvyWait || + c->monst == moIvyNext || c->monst == moIvyDead; + } + +bool isDemon(cell *c) { + return c->monst == moLesser || c->monst == moLesserM || + c->monst == moGreater || c->monst == moGreaterM; + } + +bool isWorm(cell *c) { + return c->monst == moWorm || c->monst == moWormtail || c->monst == moWormwait || + c->monst == moTentacle || c->monst == moTentacletail || c->monst == moTentaclewait || + c->monst == moTentacleEscaping; + } + +void useup(cell *c) { + c->tmp--; + if(c->tmp == 0) c->wall = waNone; + } + +bool isInactiveEnemy(cell *w) { + if(w->monst == moWormtail || w->monst == moWormwait || w->monst == moTentacletail || w->monst == moTentaclewait) + return true; + if(w->monst == moLesserM || w->monst == moGreaterM) + return true; + if(w->monst == moIvyRoot || w->monst == moIvyWait || w->monst == moIvyNext || w->monst == moIvyDead) + return true; + return false; + } + +bool isActiveEnemy(cell *w, cell *killed) { + if(w->monst == moNone || w == killed) return false; + if(isFriendly(w)) return false; + if(isInactiveEnemy(w)) return false; + if(w->monst == moIvyHead || w->monst == moIvyBranch) { + while(w != killed && w->mondir != NODIR) w = w->mov[w->mondir]; + return w != killed; + } + return true; + } + +bool isArmedEnemy(cell *w, cell *killed) { + return w->monst != moCrystalSage && isActiveEnemy(w, killed); + } + +bool player_passable(cell *w, cell *from, bool mon) { + if(w->monst && !isFriendly(w)) return false; + if(isFire(w) && items[itOrbWinter]) return true; + if(w->wall == waRoundTable && from->wall != waRoundTable) + return true; + if(items[itOrbGhost] > 1) return true; + return passable(w, from, mon, true); + } + +bool isHive(eLand l) { + return l == laHive; + } + +bool isKillable(cell *c) { + return c->monst != moShadow && !isWorm(c) && c->monst != moGreater && c->monst != moGreaterM + && c->monst != moHedge && c->monst != moFlailer; + // && !isBug(c->monst); + } + +bool isKillableSomehow(cell *c) { + return isKillable(c) + || c->monst == moHedge || c->monst == moLancer || c->monst == moFlailer; + } + +bool isNeighbor(cell *c1, cell *c2) { + for(int i=0; itype; i++) if(c1->mov[i] == c2) return true; + return false; + } + +// how many monsters are near +eMonster which; + +bool mirrorkill(cell *c) { + for(int t=0; ttype; t++) + if(c->mov[t] && isMimic(c->mov[t]) && c->mov[t]->mov[c->mov[t]->mondir] == c) + return true; + return false; + } + +// friendly==false: would the flash kill enemy monsters (i.e., allied with the witch)? +// friendly==true: would the flash kill friendly monsters (or bugs)? +bool flashWouldKill(cell *c, bool friendly) { + for(int t=0; ttype; t++) { + cell *c2 = c->mov[t]; + for(int u=0; utype; u++) { + cell *c3 = c2->mov[u]; + if(isWorm(c3)) continue; // immune to Flash + if(c3->monst == moEvilGolem) continue; // evil golems don't count + if(c3 != c && c3->monst) { + bool b = isFriendly(c3) || isBug(c3); + if(friendly ? b: !b) return true; + } + } + } + return false; + } + +int monstersnear(cell *c, cell *nocount = NULL, bool shielded = true) { + int res = 0; + bool fast = false; + if(shielded) { + if(items[itOrbShield] > 1) return 0; + fast = (items[itOrbSpeed] && !(items[itOrbSpeed] & 1)); + } + + for(int t=0; ttype; t++) { + cell *c2 = c->mov[t]; + + // consider monsters who attack from distance 2 + if(c2) + if(!thruVine(c, c2)) for(int u=2; u<=c2->type-2; u++) { + cell *c3 = c2->mov[(c->spn[t]+u) % c2->type]; + if(!c3) continue; + // only these monsters can attack from two spots... + if(c3->monst != moLancer && c3->monst != moWitchSpeed && c3->monst != moWitchFlash) continue; + // speedwitches can only attack not-fastened monsters, + // others can only attack if the move is not fastened + if(c3->monst == moWitchSpeed && items[itOrbSpeed]) continue; + if(c3->monst != moWitchSpeed && fast) continue; + // cannot attack if the immediate cell is impassable (except flashwitches) + if(c3->monst != moWitchFlash) { + if(!passable(c2, c3, !isArmedEnemy(c2, nocount), false)) continue; + if(c2 == cwt.c && items[itOrbFire]) continue; + } + // flashwitches cannot attack if it would kill another enemy + if(c3->monst == moWitchFlash && flashWouldKill(c3, false)) continue; + if(nocount && mirrorkill(c3)) continue; + res++, which = c3->monst; + } + + // consider normal monsters + if(c2 && isArmedEnemy(c2, nocount) && c2->monst != moLancer) { + if(fast && c2->monst != moWitchSpeed) continue; + // they cannot attack through vines + if(attackingForbidden(c, c2)) + continue; + // do not count if it would be killed by a mimic + if(nocount && mirrorkill(c2)) continue; + // do not include stabbed enemies + if( + (c2->monst == moHedge || (isKillable(c2) && items[itOrbThorns])) + && c2->cpdist == 1 && c != cwt.c) + continue; + res++, which = c2->monst; + } + } + + return res; + } + +// reduce c->mpdist to d; also generate the landscape + +bool checkBarriersBack(cellwalker& bb, int q=5); + +bool checkBarriersFront(cellwalker& bb, int q=5) { + if(bb.c->mpdist < BARLEV) return false; + if(bb.c->mpdist == BUGLEV) return false; + if(bb.c->bardir != NODIR) return false; + if(bb.spin == 0) {q--; if(!q) return true; } + + if(1) for(int i=0; i<7; i++) { + cellwalker bb2 = bb; + cwspin(bb2, i); cwstep(bb2); + if(bb2.c->bardir != NODIR) return false; + cwspin(bb2, 4); cwstep(bb2); + if(bb2.c->bardir != NODIR) return false; + } + + cwstep(bb); cwspin(bb, 3); cwstep(bb); cwspin(bb, 3); cwstep(bb); + return checkBarriersBack(bb, q); + } + +bool checkBarriersBack(cellwalker& bb, int q) { + // printf("back, %p, s%d\n", bb.c, bb.spin); + if(bb.c->mpdist < BARLEV) return false; + if(bb.c->mpdist == BUGLEV) return false; + if(bb.c->bardir != NODIR) return false; + // if(bb.spin == 0 && bb.c->mpdist == INFD) return true; + + if(1) for(int i=0; i<7; i++) { + cellwalker bb2 = bb; + cwspin(bb2, i); cwstep(bb2); + if(bb2.c->bardir != NODIR) return false; + cwspin(bb2, 4); cwstep(bb2); + if(bb2.c->bardir != NODIR) return false; + } + + cwspin(bb, 3); cwstep(bb); cwspin(bb, 4); + // bool create = cwstepcreates(bb); + cwstep(bb); cwspin(bb, 3); + // if(create && bb.spin == 0) return true; + return checkBarriersFront(bb, q); + } + +void setbarrier(cell *c) { + c->wall = waBarrier; + c->land = laBarrier; +/*if(isHive(c->barleft) && isHive(c->barright)) + c->wall = waWaxWall, c->land = c->barleft; */ + } + +void killIvy(cell *c) { + if(c->monst == moIvyDead) return; + for(int i=0; itype; i++) if(c->mov[i]) + if(isIvy(c->mov[i]) && c->mov[i]->mondir == c->spn[i]) + killIvy(c->mov[i]); + c->monst = moIvyDead; + } + +int buildIvy(cell *c, int children, int minleaf) { + c->mondir = NODIR; + c->monst = moIvyRoot; + + cell *child = NULL; + + int leaf = 0; + int leafchild = 0; + for(int i=0; itype; i++) { + createMov(c, i); + if(passable(c->mov[i], c, false, false)) { + if(children && !child) + child = c->mov[i], leafchild = buildIvy(c->mov[i], children-1, 5); + else + c->mov[i]->monst = (leaf++) ? moIvyWait : moIvyHead, + c->mov[i]->mondir = c->spn[i]; + } + } + + leaf += leafchild; + if(leaf < minleaf) { + if(child) killIvy(child); + killIvy(c); + return 0; + } + else return leaf; + } + +bool isIcyWall(cell *c) { + return c->wall == waNone || c->wall == waIcewall || c->wall == waFrozenLake || c->wall == waLake; + } + +bool destroyHalfvine(cell *c, eWall newwall = waNone, int tval = 6); + +void killMonster(cell *c); + +void prespill(cell* c, eWall t, int rad) { + // these monsters block spilling + if(c->monst == moSeep || c->monst == moVineSpirit || c->monst == moShark || + c->monst == moGreaterShark) + return; + // turn statues into Slimes! + if(c->wall == waBigStatue && t != waNone) { + c->wall = waNone; + c->monst = moSlimeNextTurn; + } + // slimedeath spill + if((c->monst == moSlime || c->monst == moSlimeNextTurn) && t == waNone) { + c->wall = waNone; killMonster(c); + } + // these walls block spilling completely + if(c->wall == waIcewall || c->wall == waBarrier || c->wall == waDeadTroll || + c->wall == waDune || c->wall == waAncientGrave || c->wall == waThumper || + c->wall == waFreshGrave || c->wall == waColumn || c->wall == waPartialFire || + c->wall == waDeadwall || c->wall == waWaxWall || c->wall == waCamelot || c->wall == waRoundTable || + c->wall == waBigStatue) + return; + // these walls block further spilling + if(c->wall == waCavewall || cellUnstable(c) || c->wall == waSulphur || + c->wall == waSulphurC || c->wall == waLake || c->wall == waChasm || + c->wall == waDryTree || c->wall == waWetTree || c->wall == waTemporary || + c->wall == waVinePlant || c->wall == waBonfire || c->wall == waVineHalfA || c->wall == waVineHalfB || + c->wall == waCamelotMoat) + t = waTemporary; + + if(c->wall == waSulphur) { + // remove the center as it would not look good + for(int i=0; itype; i++) if(c->mov[i] && c->mov[i]->wall == waSulphurC) + c->mov[i]->wall = waSulphur; + } + + destroyHalfvine(c); + c->wall = t; + // destroy items... + c->item = itNone; + // block spill + if(t == waTemporary) return; + // cwt.c->item = itNone; + if(rad) for(int i=0; itype; i++) if(c->mov[i]) + prespill(c->mov[i], t, rad-1); + } + +void spillfix(cell* c, eWall t, int rad) { + if(c->wall == waTemporary) c->wall = t; + if(rad) for(int i=0; itype; i++) if(c->mov[i]) + spillfix(c->mov[i], t, rad-1); + } + +void spill(cell* c, eWall t, int rad) { + prespill(c,t,rad); spillfix(c,t,rad); + } + +void degradeDemons() { + addMessage(XLAT("You feel more experienced in demon fighting!")); + int dcs = size(dcal); + for(int i=0; imonst == moGreaterM || c->monst == moGreater) + achievement_gain("DEMONSLAYER"); + if(c->monst == moGreaterM) c->monst = moLesserM; + if(c->monst == moGreater) c->monst = moLesser; + } + } + +void ivynext(cell *c); + +void earthFloor(cell *c) { + if(c->monst) return; + if(c->wall == waDeadwall) c->wall = waDeadfloor; + if(c->wall == waDune) c->wall = waNone; + if(c->wall == waAncientGrave || c->wall == waFreshGrave) c->wall = waNone; + } + +void earthWall(cell *c) { + if(c->wall == waDeadfloor || c->wall == waDeadfloor2 || c->wall == waEarthD) { + c->item = itNone; + c->wall = waDeadwall; + } + if(c->wall == waNone && c->land == laDesert) { + c->item = itNone; + c->wall = waDune; + } + } + +bool isWitch(eMonster m) { + // evil golems don't count + return m >= moWitch && m < moWitch+NUMWITCH-1; + } + +void killMonster(cell *c) { + DEB("killmonster"); + eMonster m = c->monst; + + if(!m) return; + if(isWorm(c)) return; + if(m == moShadow) return; + if(m == moGolemMoved) m = moGolem; + if(m == moKnightMoved) m = moKnight; + if(m == moSlimeNextTurn) m = moSlime; + if(m == moLesserM) m = moLesser; + if(m == moGreater) m = moLesser; + if(m == moGreaterM) m = moLesser; + kills[m]++; + + if(m == moTroll) { + destroyHalfvine(c); + c->wall = cellUnstableOrChasm(c) ? waChasm : waDeadTroll; + c->item = itNone; + for(int i=0; itype; i++) if(c->mov[i]) { + c->mov[i]->item = itNone; + if(c->mov[i]->wall == waDeadwall || c->mov[i]->wall == waDeadfloor2) c->mov[i]->wall = waCavewall; + if(c->mov[i]->wall == waDeadfloor) c->mov[i]->wall = waCavefloor; + } + } + if(m == moMiner) { + destroyHalfvine(c); + c->wall = cellUnstableOrChasm(c) ? waChasm : waNone; + for(int i=0; itype; i++) if(passable(c->mov[i], c, true, true)) { + destroyHalfvine(c->mov[i]); + c->mov[i]->wall = cellUnstableOrChasm(c) ? waChasm : waNone; + if(c->mov[i]->monst == moSlime || c->mov[i]->monst == moSlimeNextTurn) + killMonster(c->mov[i]); + } + } + if(m == moVineBeast) { + destroyHalfvine(c); + c->wall = cellUnstableOrChasm(c) ? waChasm : waVinePlant; + c->item = itNone; + } + if(m == moVineSpirit) { + destroyHalfvine(c); + c->wall = waNone; + } + if(isWitch(m) && (c->wall == waBonfire || passable(c, NULL, true, false)) && !c->item) { + if(m == moWitchFire) c->item = itOrbFire; + if(m == moWitchFlash) c->item = itOrbFlash; + if(m == moWitchGhost) c->item = itOrbGhost; + if(m == moWitchWinter) c->item = itOrbWinter; + if(m == moWitchSpeed) c->item = itOrbSpeed; + if(c->wall == waBonfire && itemBurns(c->item)) + c->item = itNone; + } + if(m == moFireFairy) { + c->wall = cellUnstableOrChasm(c) ? waChasm : waBonfire; + c->item = itNone, c->tmp = 50; + } + if(m == moPyroCultist && c->item == itNone && c->wall != waChasm) { + // a reward for killing him before he shoots! + c->item = itOrbDragon; + } + if(m == moSlime) { c->monst = moNone; spill(c, c->wall, 2); } + // if(c->monst == moShark) c->heat += 1; + // if(c->monst == moGreaterShark) c->heat += 10; + if(isIcyLand(c)) { + if(m == moCultist) c->heat += 3; + if(m == moPyroCultist) c->heat += 6; + if(m == moLesser) c->heat += 10; + } + if(m == moLesser && !(kills[m] % 10)) + degradeDemons(); + if(isIvy(c)) { + eMonster m = c->monst; + /*if((m == moIvyBranch || m == moIvyHead) && c->mov[c->mondir]->monst == moIvyRoot) + ivynext(c, moIvyNext); */ + killIvy(c); + if(m == moIvyBranch || m == moIvyHead || m == moIvyNext) { + int qty = 0; + cell *c2 = c->mov[c->mondir]; + for(int i=0; itype; i++) + if(c2->mov[i]->monst == moIvyWait && c2->mov[i]->mondir == c2->spn[i]) + qty++; + if(c->mov[c->mondir]->monst == moIvyRoot || qty) { + c->monst = moIvyNext; + /* c->monst = moIvyHead; + ivynext(c); + if(c->monst == moIvyHead) c->monst = moIvyNext; + else c->monst = moNone; */ + } + else { + c->mov[c->mondir]->monst = moIvyHead; + } + } + } + else c->monst = moNone; + + if(m == moEarthElemental) earthWall(c); + } + +void burnMonstersAndItems(cell *c, int val, eWall firetype = waBonfire) { + if(itemBurns(c->item)) + addMessage(XLAT("%The1 burns!", c->item)), c->item = itNone; + if(c->monst && c->monst != moGhost && !isWorm(c) && c->monst != moShadow) { + addMessage(XLAT("%The1 burns!", c->monst)); + killMonster(c); + } + c->tmp = val; + c->wall = firetype; + } + +void flameHalfvine(cell *c, int val) { + burnMonstersAndItems(c, val); + c->wall = waPartialFire; + } + +bool destroyHalfvine(cell *c, eWall newwall, int tval) { + if(cellHalfvine(c)) { + for(int t=0; ttype; t++) if(c->mov[t]->wall == c->wall) { + if(newwall == waPartialFire) burnMonstersAndItems(c->mov[t], tval, newwall); + else c->mov[t]->wall = newwall; + } + if(newwall == waPartialFire) burnMonstersAndItems(c, tval, newwall); + else c->wall = newwall; + return true; + } + return false; + } + +bool orbChance(cell *c, eLand usual, int chthere, int chcross) { + if(c->land == usual) return chthere && rand() % chthere == 0; + if(chcross && c->land == laCrossroads) { + chcross = (chcross / 50) * (50 + items[itHyperstone]); + return rand() % chcross == 0; + } + return false; + } + +void buildBarrier(cell *c) { + // printf("build barrier at %p", c); + if(c->wall == waBarrier) { + // printf("-> ready\n"); + return; + } +// if(c->wall == waWaxWall) return; + if(c->mpdist > BARLEV) { + // printf("-> too far\n"); + return; // == INFD) return; + } + + cellwalker bb(c, c->bardir); setbarrier(bb.c); + cwstep(bb); + bb.c->barleft = c->barright; + bb.c->barright = c->barleft; + setbarrier(bb.c); + cwspin(bb, 2); cwstep(bb); bb.c->land = c->barleft; cwstep(bb); + cwspin(bb, 2); cwstep(bb); bb.c->land = c->barright; cwstep(bb); + cwspin(bb, 2); + + cwspin(bb, 3); cwstep(bb); + bb.c->barleft = c->barright; + bb.c->barright = c->barleft; + setbarrier(bb.c); + cwspin(bb, 3); cwstep(bb); + + bb.c->bardir = bb.spin; + bb.c->barleft = c->barright; + bb.c->barright = c->barleft; + // printf("#1\n"); + buildBarrier(bb.c); + + for(int a=-3; a<=3; a++) if(a) { + bb.c = c; bb.spin = c->bardir; cwspin(bb, a); cwstep(bb); + bb.c->land = a > 0 ? c->barright : c->barleft; + } + + bb.c = c; bb.spin = c->bardir; + cwspin(bb, 3); cwstep(bb); cwspin(bb, 4); bb.c->land = c->barright; cwstep(bb); cwspin(bb, 3); + bb.c->bardir = bb.spin; + bb.c->barleft = c->barright; + bb.c->barright = c->barleft; + // printf("#2\n"); + buildBarrier(bb.c); + } + +void chasmify(cell *c) { + c->wall = waChasm; c->item = itNone; + int q = 0; + cell *c2[10]; + for(int i=0; itype; i++) if(c->mov[i] && c->mov[i]->mpdist > c->mpdist && cellUnstable(c->mov[i])) + c2[q++] = c->mov[i]; + if(q) { + cell *c3 = c2[rand() % q]; + c3->wall = waChasmD; + } + } + +void chasmifyEarth(cell *c) { + int q = 0; + int d2[10]; + for(int i=2; i<=c->type-2; i++) { + int j = (i+c->mondir)%c->type; + cell *c2 = c->mov[j]; + if(c2 && c2->mpdist > c->mpdist && ( + c2->wall == waDeadfloor || c2->wall == waDeadwall || + c2->wall == waDeadfloor2)) + d2[q++] = j; + } + if(!q) printf("no further move!\n"); + if(q) { + int d = d2[rand() % q]; + cell *c3 = c->mov[d]; + c3->wall = waEarthD; + for(int i=0; itype; i++) { + cell *c4 = createMov(c3, i); + earthFloor(c4); + } + c3->mondir = c->spn[d]; + } + earthWall(c); c->item = itNone; + } + +eLand getNewLand(eLand old) { + eLand tab[32]; + int cnt = 0; + +/* if(isHive(old) && rand() % 100 < 90) { + eLand n = old; + while(n == old) n = eLand(laHive0 + rand() % 3); + return n; + } */ + + // return (rand() % 2) ? laMotion : laJungle; + + // the basic lands, always available + tab[cnt++] = laCrossroads; + tab[cnt++] = laIce; + tab[cnt++] = laDesert; + tab[cnt++] = laJungle; + if(old != laDeadCaves) tab[cnt++] = laCaves; + + // the advanced lands + if(gold() >= 30) { + tab[cnt++] = laCrossroads; + tab[cnt++] = laAlchemist; + tab[cnt++] = laMirror; + tab[cnt++] = laMotion; + } + + if(gold() >= 60) { + tab[cnt++] = laCrossroads; + tab[cnt++] = laRlyeh; + if(old != laDeadCaves && items[itGold] >= 5 && items[itFernFlower] >= 5) tab[cnt++] = laFjord; + if(old != laPower) tab[cnt++] = laDryForest; + if(old != laPower) tab[cnt++] = laWineyard; + if(old != laCaves && old != laFjord && items[itGold] >= 10) tab[cnt++] = laDeadCaves; + } + + if(tkills() >= 100) { + tab[cnt++] = laGraveyard; + if(gold() >= 60) tab[cnt++] = laHive; + } + + if(hellUnlocked()) { + tab[cnt++] = laCrossroads; + tab[cnt++] = laHell; + } + + if(items[itHell] >= 10) { + tab[cnt++] = laCocytus; + if(old != laWineyard && old != laDryForest) tab[cnt++] = laPower; + } + + eLand n = old; + while(n == old) n = tab[rand() % cnt]; + + return n; + } + +bool notDippingFor(eItem i) { + int v = items[i] - currentLocalTreasure; + if(v <= 10) return true; + if(v >= 20) return false; + return v >= rand() % 10 + 10; + } + +bool notDippingForExtra(eItem i, eItem x) { + int v = items[i] - min(items[x], currentLocalTreasure); + if(v <= 10) return true; + if(v >= 20) return false; + return v >= rand() % 10 + 10; + } + +eLand euland[65536]; + +eLand switchable(eLand nearland, eLand farland, eucoord c) { + if(nearland == laCrossroads) { + if(rand() % 4 == 0 && (short(c)%3==0)) + return laBarrier; + return laCrossroads; + } + else if(nearland == laBarrier) { + return getNewLand(farland); + } + else { + if(rand() % 20 == 0 && (short(c)%3==0)) + return laBarrier; + return nearland; + } + } + +eLand getEuclidLand(eucoord c) { + if(euland[c]) return euland[c]; + if(c == 0 || c == eucoord(-1) || c == 1) + return euland[c] = laCrossroads; + if(euland[eucoord(c-2)] && ! euland[eucoord(c-1)]) getEuclidLand(c-1); + if(euland[eucoord(c+2)] && ! euland[eucoord(c+1)]) getEuclidLand(c+1); + if(euland[eucoord(c-1)]) return + euland[c] = switchable(euland[c-1], euland[eucoord(c-2)], c); + if(euland[eucoord(c+1)]) return + euland[c] = switchable(euland[c+1], euland[eucoord(c+2)], c); + return euland[c] = laCrossroads; + } + +void createBugArmy(cell *c); + +int newRoundTableRadius() { + return 28 + 2 * items[itHolyGrail]; + } + +int roundTableRadius(cell *c) { + if(euclid) return 28; + return c->master->alt->alt->fjordval & GRAIL_RADIUS_MASK; + } + +bool grailWasFound(cell *c) { + if(euclid) return items[itHolyGrail]; + return c->master->alt->alt->fjordval & GRAIL_FOUND; + } + +int euclidAlt(short x, short y) { + if(euclidland == laTemple) { + return max(int(x), x+y); + } + else return eudist(x-20, y-10); + } + +int celldistAltRelative(cell *c) { + return celldistAlt(c) - roundTableRadius(c); + } + +heptagon *createAlternateMap(cell *c, int rad, hstate firststate); + +void generateAlts(heptagon *h); + +void buildCamelotWall(cell *c) { + c->wall = waCamelot; + for(int i=0; itype; i++) { + cell *c2 = createMov(c, i); + if(c2->wall == waNone && celldistAlt(c2) > celldistAlt(c) && c2->monst == moNone) + c2->wall = waCamelotMoat; + } + } + +// This function generates all lands. Warning: it's very long! +void setdist(cell *c, int d, cell *from) { + DEB("setdist"); + if(signed(c->mpdist) <= d) return; + c->mpdist = d; + + if(d >= BARLEV) { + if(!c->land) c->land = from->land; + if(c->land == laTemple) c->land = laRlyeh; + if(c->land == laCamelot) c->land = laCrossroads; + + if(euclid) { + c->land = euclidland; + if(euclidland == laCrossroads) { + eucoord x, y; + decodeMaster(c->master, x, y); + c->land = getEuclidLand(y+2*x); + } + } + } + + if(d == BARLEV && !euclid) { + + if(c->type == 7 && rand() % 10000 < ( + showoff ? (cwt.c->mpdist > 7 ? 0 : 10000) : + c->land == laCrossroads ? 5000 : 50) && + c->land != laGameBoard) { + + int bd = 2 + (rand() % 2) * 3; + + cellwalker bb(c, bd); + cellwalker bb2 = bb; + + if(checkBarriersFront(bb) && checkBarriersBack(bb2)) { + c->bardir = bd; + eLand oldland = c->land; + eLand newland = getNewLand(oldland); + if(showoff) newland = showlist[(showid++) % 10]; + landcount[newland]++; + + if(bd == 5) c->barleft = oldland, c->barright = newland; + else c->barleft = newland, c->barright = oldland; + } + } + + if(c->land == laCrossroads && c->type == 7 && rand() % 2000 < 200 && items[itEmerald] >= 5) { + int rtr = newRoundTableRadius(); + heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin); + if(alt) { + alt->fjordval = rtr; + } + } + + if(c->land == laRlyeh && c->type == 7 && rand() % 2000 < 100 && items[itStatue] >= 5) + createAlternateMap(c, 2, hsA); + + if(c->bardir != NODIR && c->bardir != NOBARRIERS) + buildBarrier(c); + } + + if(d < 10) { + explore[d]++; + exploreland[d][c->land]++; + + if(d < BARLEV) + for(int i=0; itype; i++) { + createMov(c, i); + setdist(c->mov[i], d+1, c); + } + + if(d==8 && c->land == laFjord) { + if(euclid) { + eucoord x, y; + decodeMaster(c->master, x, y); + if(((y-2)&7) < 4) c->wall = waCavewall; + else c->wall = waCavefloor; + } + else { + int v = fjordval(c); + if((v&3) >= 2) + c->wall = waCavewall; + else c->wall = waCavefloor; + } + } + + if(d==8 && c->land == laPower) { + int v; + if(euclid) { + eucoord x, y; + decodeMaster(c->master, x, y); + int y0 = ((short)y) % 6; + if(y0<0) y0+=6; + if(y0 == 3 || y0 == 4) v=24; else v=0; + } + else v = fjordval(c); + v &= ~3; + if((v == 24 || v == 32 || v == 56)) + c->wall = waBonfire, c->tmp = 9; + else if(rand() % 100 < 10) { + c->wall = waGlass; + eItem protectedItems[17] = { + itPower, itPower, itPower, itPower, itPower, itPower, + itOrbLightning, itOrbLightning, itOrbThorns, itOrbThorns, + itOrbInvis, itOrbInvis, + itOrbShield, itOrbTeleport, itOrbPsi, + itOrbDragon, itOrbIllusion + }; + c->item = protectedItems[rand() % 17]; + } + } + + if(d==8 && c->land == laWineyard) { + if(euclid) { + eucoord x, y; + decodeMaster(c->master, x, y); + int dy = ((short)y)%3; if(dy<0) dy += 3; + if(dy == 1) c->wall = waVinePlant; + } + else { + int v = fjordval(c); + int w = v / 4; + if(w == 9 || w == 10 || w == 7 || w == 8) { + c->wall = waVinePlant; + } + else if(v == 24 || v == 58 || v == 26 || v == 56) + c->wall = waVineHalfA; + else if(v == 25 || v == 59 || v == 27 || v == 57) + c->wall = waVineHalfB; + else c->wall = waNone; + } + } + + if(d == 7 && cellHalfvine(c)) { + int i = -1; + for(int k=0; ktype; k++) if(c->mov[k] && c->mov[k]->wall == c->wall) + i = 0; + if(i == -1) c->wall = waNone; + } + + // 24-58 + // 26-56 + if(d == 9) { + + // if(c->land == laIce && ((celldist(c) % 10) + 10) % 10 == 5) + // c->wall = waColumn; + + if(c->land == laIce) if(rand() % 100 < 5 && c->wall != waBarrier) { + c->wall = waIcewall; + for(int i=0; itype; i++) if(rand() % 100 < 50) { + createMov(c, i); + setdist(c->mov[i], d+1, c); + cell *c2 = c->mov[i]; + if(c2->wall == waBarrier || c2->land != laIce) continue; + c2->wall = waIcewall; + for(int j=0; jtype; j++) if(rand() % 100 < 20) { + createMov(c2, j); + setdist(c->mov[i], d+2, c); + cell *c3 = c2->mov[j]; + if(c3->wall == waBarrier || c3->land != laIce) continue; + c3->wall = waIcewall; + } + } + } + + if(c->land == laIce || c->land == laCocytus) if(c->wall == waIcewall && items[itDiamond] >= 5 && rand() % 200 == 1) + c->wall = waBonfire, c->tmp = -1;; + + if(c->land == laCaves) + c->wall = rand() % 100 < 55 ? waCavewall : waCavefloor; + + if(c->land == laDeadCaves) { + int i = rand() % 100; + if(i<50) c->wall = waDeadwall; + else if(i<55) c->wall = waDeadfloor2; + else c->wall = waDeadfloor; + } + + if(c->land == laAlchemist) + c->wall = rand() % 2 ? waFloorA : waFloorB; + + if(c->land == laDryForest) + c->wall = rand() % 100 < 50 ? (rand() % 100 < 50 ? waDryTree : waWetTree) : + waNone; + + if(c->land == laGraveyard && ishept(c)) + c->wall = rand() % 5 ? waAncientGrave : waFreshGrave; + + if(c->land == laRlyeh) { + if(rand() % 500 < 5) { + for(int i=0; itype; i++) { + createMov(c, i); + setdist(c->mov[i], d+1, c); + if(c->mov[i] && c->mov[i]->land == laRlyeh) + c->mov[i]->wall = waColumn; + } + + for(int j=0; j<2; j++) { + int i = rand() % c->type; + if(c->mov[i] && c->mov[i]->land == laRlyeh) + c->mov[i]->wall = waNone; + } + } + if(ishept(c) && rand() % 2) c->wall = waColumn; + } + + if(c->land == laHell) { + if(rand() % 100 < 4) { + for(int i=0; itype; i++) { + createMov(c, i); + setdist(c->mov[i], d+1, c); + if(c->mov[i] && c->mov[i]->land == laHell) + if(c->mov[i]->wall != waSulphurC) + c->mov[i]->wall = waSulphur; + } + + c->wall = waSulphurC; + } + } + + if(c->land == laCocytus) { + if(c->wall == waNone) c->wall = waFrozenLake; + if(rand() % 100 < 5) { + for(int i=0; itype; i++) { + createMov(c, i); + setdist(c->mov[i], d+1, c); + if(c->mov[i] && c->mov[i]->land == laCocytus) + c->mov[i]->wall = waLake; + } + + c->wall = waLake; + + if(rand() % 500 < 100 + 2 * (items[itSapphire])) + c->monst = moShark; + } + } + + if(isHive(c->land) && rand() % 2000 < 2) + createBugArmy(c); + + if((c->land == laCrossroads && !euclid) || c->land == laCamelot) + if(euclid || c->master->alt) { + int d = celldistAltRelative(c); + { + eucoord x,y; + decodeMaster(c->master, x, y); + } + if(d <= 14) { + if(!euclid) generateAlts(c->master); + c->bardir = NOBARRIERS; + int d = celldistAltRelative(c); + if(d == 10) { + if(ishept(c)) buildCamelotWall(c); + else { + if(!euclid) for(int i=0; i<7; i++) generateAlts(c->master->move[i]); + int q = 0; + for(int t=0; t<6; t++) { + createMov(c, t); + if(celldistAltRelative(c->mov[t]) == 10 && !ishept(c->mov[t])) q++; + } + if(q == 1) buildCamelotWall(c); + // towers of Camelot + if(q == 0) { + c->monst = moKnight; + for(int i=0; i<6; i++) + buildCamelotWall(c->mov[i]); + for(int i=0; itype; i++) if(celldistAltRelative(c->mov[i]) < d) + c->mondir = i; + } + } + } + if(d == 0) c->wall = waRoundTable; + if(celldistAlt(c) == 0) c->item = itHolyGrail; + if(d < 0 && rand() % 7000 <= 10 + items[itHolyGrail] * 5) { + eMonster m[3] = { moHedge, moLancer, moFlailer }; + c->monst = m[rand() % 3]; + } + if(d == 1) { + // roughly as many knights as table cells + if(rand() % 1720 < 1000) + c->monst = moKnight; + if(!euclid) for(int i=0; i<7; i++) generateAlts(c->master->move[i]); + for(int i=0; itype; i++) + if(c->mov[i] && celldistAltRelative(c->mov[i]) < d) + c->mondir = (i+3) % 6; + } + if(d <= 10) c->land = laCamelot; + if(d > 10 && !euclid) c->land = laCrossroads; + } + } + + if((c->land == laRlyeh && !euclid) || c->land == laTemple) { + if(euclid || (c->master->alt && c->master->alt->distance <= 2)) { + if(!euclid) generateAlts(c->master); + c->bardir = NOBARRIERS; + int d = celldistAlt(c); + if(d <= 0) { + c->land = laTemple, c->wall = waNone, c->monst = moNone, c->item = itNone; + } + if(d % TEMPLE_EACH==0) { + if(ishept(c)) + c->wall = waColumn; + else { + if(!euclid) for(int i=0; i<7; i++) generateAlts(c->master->move[i]); + int q = 0; + for(int t=0; t<6; t++) { + createMov(c, t); + if(celldistAlt(c->mov[t]) % TEMPLE_EACH == 0 && !ishept(c->mov[t])) q++; + } + if(q == 2) c->wall = waColumn; + } + } + } + } + + if(isHive(c->land) && rand() % 2000 < 100 && !c->wall && !c->item && !c->monst) { + int nww = 0; + for(int i=0; itype; i++) if(c->mov[i] && c->mov[i]->wall == waWaxWall) + nww++; + if(nww == 0) { + c->wall = waWaxWall; + c->monst = moNone; + c->heat = rand() & 0xFFFFFF; + } + /* for(int i=0; itype; i++) { + if(rand() % 6 < 5) { + createMov(c,i); + cell *c2 = c->mov[i]; + c2->wall = waWaxWall; + c2->monst = moNone; + } + } */ + } + + if(c->land == laDesert) { + if(rand() % 100 < 5) { + for(int i=0; itype; i++) { + createMov(c, i); + setdist(c->mov[i], d+1, c); + if(c->mov[i] && c->mov[i]->land == laDesert) + c->mov[i]->wall = waDune; + } + + for(int j=0; j<2; j++) { + int i = rand() % c->type; + if(c->mov[i] && c->mov[i]->land == laDesert) + c->mov[i]->wall = waNone; + } + } + + if(rand() % 300 == 1 && items[itSpice] >= 5) + c->wall = waThumper, c->tmp = -1; + } + } + + if(d == 7 && c->land == laCaves && c->wall == waCavewall && rand() % 5000 < items[itGold]) + c->monst = moSeep; + + if(d == 7 && c->land == laFjord && c->wall == waCavewall && rand() % 5000 < items[itEmerald]) + c->monst = moSeep; + + if(d == 7 && c->land == laDeadCaves && c->wall == waDeadwall && rand() % 1000 < items[itSilver]) + c->monst = moSeep; + + if(d == 7 && c->wall == waVinePlant && rand() % 100 < 10) + c->monst = moVineSpirit; + + // repair the buggy walls flowing in from another land, like ice walls flowing into the Caves + if(d == 7 && c->land == laCaves && c->wall != waCavewall && c->wall != waCavefloor) + c->wall = waCavefloor; + + if(d == 7 && c->land == laDeadCaves && c->wall != waDeadwall && + c->wall != waDeadfloor && c->wall != waDeadfloor2 && c->wall != waEarthD) + c->wall = waDeadfloor2; + + if(d == 7 && c->land == laCocytus && c->wall != waFrozenLake && c->wall != waLake && c->wall != waIcewall) + c->wall = waFrozenLake; + + if(d == 7 && c->land == laAlchemist && c->wall != waFloorA && c->wall != waFloorB) + c->wall = waFloorA; + + if(d == 7 && c->wall == waIcewall && c->land != laIce && c->land != laCocytus) + c->wall = waNone; + + if(d == 7 && c->wall == waChasmD) { + chasmify(c); + } + + if(d == 7 && c->wall == waEarthD) { + chasmifyEarth(c); + } + + // seal entrances to the Land of Power. + if(d == 7 && c->land == laPower && c->type == 7) { + bool onwall = false; + for(int i=0; i<7; i++) if(c->mov[i] && c->mov[i]->land != laPower) + onwall = true; + if(!onwall) for(int i=0; i<7; i++) { + cell *c2 = c->mov[i]; + cell *c3 = c2->mov[(c->spn[i] + 3) % 6]; + if(c3->land != laPower && c3->land != laBarrier) + if(c2->wall != waBonfire && c2->wall != waGlass) { + if(c->wall == waBonfire) c->monst = moWitchWinter; + else if(c->wall == waGlass) c->monst = moWitchGhost; + else c->monst = moEvilGolem; + } + } + } + + if(d == 7 && passable(c, NULL, false, false)) { + if(c->land == laBarrier) c->wall = waBarrier; + } + + if(d == 7 && passable(c, NULL, false, false) && !safety) { + int hard = items[itOrbYendor] * 5; + + if(c->land == laIce) { + if(rand() % 5000 < 100 + 2 * (kills[moYeti] + kills[moWolf]) && notDippingFor(itDiamond)) + c->item = itDiamond; + if(rand() % 8000 < 2 * (items[itDiamond] + hard)) + c->monst = rand() % 2 ? moYeti : moWolf; + } + if(c->land == laCaves) { + if(rand() % 5000 < 100 + 2 * (kills[moTroll] + kills[moGoblin]) && notDippingFor(itGold)) + c->item = itGold; + if(rand() % 8000 < 10 + 2 * (items[itGold] + hard)) + c->monst = rand() % 2 ? moTroll : moGoblin; + } + if(c->land == laDeadCaves) { + if(rand() % 5000 < 100 + 2 * (kills[moDarkTroll] + kills[moEarthElemental]) && notDippingFor(itSilver)) + c->item = itSilver; + if(rand() % 16000 < (items[itSilver] + hard)) { + c->monst = moEarthElemental; + for(int i=0; itype; i++) { + cell *c2 = c->mov[i]; + earthFloor(c2); + } + for(int i=0; itype; i++) if(c->mov[i]->mpdist < c->mpdist) c->mondir = i; + chasmifyEarth(c); c->wall = waDeadfloor2; + } + else if(rand() % 8000 < 60 + 8 * (items[itSilver] + hard)) { + if(rand() % 100 < 25) { + } + else c->monst = rand() % 2 ? moDarkTroll : moGoblin; + } + } + if(c->land == laDesert) { + if(rand() % 5000 < 100 + 2 * (kills[moWorm] + kills[moDesertman]) && notDippingFor(itSpice)) + c->item = itSpice; + if(rand() % 8000 < 10 + 2 * (items[itSpice] + hard)) + c->monst = rand() % 2 ? moWorm : moDesertman, + c->mondir = NODIR; + } + if(c->land == laWineyard) { + if(rand() % 5000 < 100 + 2 * (kills[moVineBeast] + kills[moVineSpirit]) && notDippingFor(itWine)) + c->item = itWine; + if(rand() % 8000 < 12 * (items[itWine] + hard)) + c->monst = moVineBeast; + } + if(c->land == laFjord) { + if(rand() % 1000 < 100 + 2 * (kills[moMiner] + kills[moLancer] + kills[moFlailer]) && notDippingFor(itEmerald)) { + // do not destroy walls! + bool ok = true; + for(int i=0; itype; i++) if(c->mov[i]->wall == waCavewall) ok = false; + if(ok) c->item = itEmerald; + } + if(rand() % 8000 < 50 + 10 * (items[itEmerald] + hard)) { + static eMonster fjordmonsters[4] = { moHedge, moLancer, moFlailer, moMiner }; + c->monst = fjordmonsters[rand() % 4]; + } + } + if(c->land == laJungle) { + if(rand() % 5000 < 25 + 2 * (kills[moIvyRoot] + kills[moMonkey]) && notDippingFor(itRuby)) + c->item = itRuby; + if(rand() % 15000 < 5 + 1 * (items[itRuby] + hard)) + c->monst = moMonkey; + else if(rand() % 80000 < 5 + items[itRuby] + hard) + c->monst = moEagle; + else if(ishept(c) && rand() % 4000 < 300 + items[itRuby]) { + bool hard = rand() % 100 < 25; + if(hard ? buildIvy(c, 1, 9) : buildIvy(c, 0, c->type)) + c->item = itRuby; + } + } + if(c->land == laAlchemist) { + if(rand() % 5000 < 25 + min(kills[moSlime], 200) && notDippingFor(itElixir)) + c->item = itElixir; + else if(rand() % 3500 < 10 + items[itElixir] + hard) + c->monst = moSlime; + } + if(c->land == laPower) { + if(rand() % (5000+50*items[itPower]) < 1200) { + eItem powerorbs[6] = { + itOrbFlash, itOrbSpeed, itOrbFire, itOrbWinter, itOrbGhost, itOrbLife}; + c->item = powerorbs[rand() % 6]; + } + else if(c->type == 6 && rand() % 5000 < 10) + c->wall = rand() % 2 ? waMirror : waCloud; + else if(rand() % 1000 < 10 + (items[itPower] ? 10:0) + (items[itPower] + hard)) + c->monst = eMonster(moWitch + rand() % NUMWITCH); + } + if(c->land == laCrossroads) { + if(c->type == 6 && rand() % 8000 < 120 && items[itShard] >= 10) + c->wall = rand() % 2 ? waMirror : waCloud; + else if(hyperstonesUnlocked() && rand() % 5000 < tkills() && notDippingFor(itHyperstone)) + c->item = itHyperstone; + else if(rand() % 4000 < items[itHyperstone] + 2 * items[itHolyGrail]) { + // only interesting monsters here! + static eMonster m[14] = { + moWorm, moTroll, moEagle, + moLesser, moGreater, moPyroCultist, moGhost, + moFireFairy, moIvyRoot, moTentacle, moHedge, + moLancer, moFlailer, moVineBeast + }; + eMonster cm = m[rand() % 14]; + if(cm == moIvyRoot) buildIvy(c, 0, c->type); + else c->monst = cm; + if(cm == moWorm || cm == moTentacle) + c->mondir = NODIR; + } + } + if(c->land == laMirror) { + if(c->type == 6 && rand() % 5000 < 120 && notDippingFor(itShard)) + c->wall = rand() % 2 ? waMirror : waCloud; + if(rand() % 12000 < 8 + items[itShard] + hard) + c->monst = moRanger; + else if(rand() % 60000 < 8 + items[itShard] + hard) + c->monst = moEagle; + } + if(c->land == laGraveyard) { + if(rand() % 5000 < 30 + 2 * (kills[moZombie] + kills[moGhost] + kills[moNecromancer]) && notDippingFor(itBone)) + c->item = itBone; + if(rand() % 20000 < 10 + items[itBone] + hard + (kills[moZombie] + kills[moGhost] + kills[moNecromancer])/60) { + eMonster grm[6] = { moZombie, moZombie, moZombie, moGhost, moGhost, moNecromancer}; + c->monst = grm[rand() % 6]; + } + } + if(c->land == laRlyeh) { + if(rand() % 5000 < 30 + 2 * (kills[moCultist] + kills[moTentacle] + kills[moPyroCultist]) && notDippingFor(itStatue)) + c->item = itStatue; + if(rand() % 8000 < 5 + items[itStatue] + hard) + c->monst = moTentacle, c->item = itStatue, c->mondir = NODIR; + else if(rand() % 12000 < 5 + items[itStatue] + hard) + c->monst = rand() % 3 ? ((rand() % 40 < items[itStatue]-25) ? moCultistLeader : moCultist) : moPyroCultist; + else if(rand() % 8000 < 5 + items[itStatue] + hard && c->type == 6) { + for(int t=0; ttype; t++) { + if(c->mov[t] && c->mov[t]->monst == moNone && (c->wall == waNone || c->wall == waColumn)) + c->mov[t]->wall = ishept(c->mov[t]) ? waColumn : waNone; + if(c->mov[t]->wall == waColumn) + c->mov[t]->item = itNone; + } + if(buildIvy(c, 0, 3)) c->item = itStatue; + } + } + if(c->land == laTemple) { + // depth! + int d = celldistAlt(c); + // remember: d is negative + if(d % TEMPLE_EACH == 0) { + if(rand() % 5000 < 20 - 2*d) + c->monst = moTentacle, c->mondir = NODIR; + } + else { + int d0 = d % TEMPLE_EACH; + if(d0<0) d0=-d0; + if(rand() % 100 < 30) // && d0 != 1 && d0 != TEMPLE_EACH-1) + c->wall = waBigStatue; + else if(rand() % 20000 < -d) + c->monst = rand() % 3 ? moCultist : moPyroCultist; + else if(rand() % 100000 < -d) + c->monst = moCultistLeader; + else if(rand() % 5000 < 250) + c->item = itGrimoire; + else if(rand() % 5000 < 10 && -d > TEMPLE_EACH * 10) + c->item = itOrbDragon; + } + } + if(c->land == laDryForest) { + if(rand() % 5000 < 100 + 2 * (kills[moFireFairy]*2 + kills[moHedge]) && notDippingFor(itFernFlower)) + c->item = itFernFlower; + if(rand() % 4000 < 40 + items[itFernFlower] + hard) + c->monst = moHedge; + else if(rand() % 8000 < 2 * items[itFernFlower] + hard) + c->monst = moFireFairy; + } + if(c->land == laHell) { + if(rand() % 1500 < 30 + (kills[moCultist] + kills[moTentacle]) && notDippingFor(itHell)) + c->item = itHell; + if(rand() % 8000 < 40 + items[itHell] + hard) + c->monst = moLesser; + else if(rand() % 24000 < 40 + items[itHell] + hard) + c->monst = moGreater; + } + if(c->land == laCocytus) { + if(rand() % 5000 < 100 + 2 * (kills[moShark] + kills[moGreaterShark] + kills[moCrystalSage]) && notDippingFor(itSapphire)) + c->item = itSapphire; + if(rand() % 5000 < 2 * (items[itSapphire] + hard)) { + eMonster ms[3] = { moYeti, moGreaterShark, moCrystalSage }; + c->monst = ms[rand() % 3]; + if(c->monst == moGreaterShark) c->wall = waLake; + } + } + if(c->land == laMotion) { + if(rand() % 1500 < 30 + (kills[moRunDog]) && notDippingFor(itFeather)) + c->item = itFeather; + if(rand() % 20000 < 25 + items[itFeather] + hard) { + c->monst = moRunDog; + // preset the movement direction + // this will make the dog go in the direction of the center, + // if the player is unreachable/invisible + for(int d=0; dtype; d++) if(c->mov[d] == from) { + c->mondir = (d+3) % c->type; + } + chasmify(c); + } + } + if(c->land == laHive) { + if(isHive(c->land) && rand() % 6000 < (items[itRoyalJelly] + hard-15)) + c->monst = eMonster(moBug0 + rand() % BUGCOLORS); + + /* if(rand() % 1500 < 30 + (kills[moBug0] + kills[moBug1] + kills[moBug2]) && notDippingFor(itRoyalJelly)) + c->item = itRoyalJelly; */ + /* if(rand() % 2000 < 2) + c->monst = eMonster(moBug0 + rand() % 3); */ + } + if(!c->item && c->wall != waCloud && c->wall != waMirror) { + if(orbChance(c, laJungle, 1200, 1500) && items[itRuby] >= 10) + c->item = itOrbLightning; + if(orbChance(c, laIce, 2000, 1500) && items[itDiamond] >= 10) + c->item = itOrbFlash; + if(orbChance(c, laCaves, 1800, 2000) && items[itGold] >= 10) + c->item = itOrbLife; + if(orbChance(c, laAlchemist, 600, 800) && items[itElixir] >= 10) + c->item = itOrbSpeed; + if(orbChance(c, laGraveyard, 200, 200) && items[itBone] >= 10) + c->item = itGreenStone; + if(orbChance(c, laDesert, 2500, 600) && items[itSpice] >= 10) + c->item = itOrbShield; + if(orbChance(c, laHell, 2000, 1000) && items[itHell] >= 10) + c->item = itOrbYendor; + if(orbChance(c, laRlyeh, 1500, 1000) && items[itStatue] >= 10) + c->item = itOrbTeleport; + if(orbChance(c, laMotion, 2000, 700) && items[itFeather] >= 10) { + c->item = itOrbSafety; + } + + if(orbChance(c, laIce, 1500, 0) && items[itDiamond] >= 10) + c->item = itOrbWinter; + if(orbChance(c, laDryForest, 2500, 0) && items[itFernFlower] >= 10) + c->item = itOrbWinter; + if(orbChance(c, laCocytus, 1500, 1500) && items[itSapphire] >= 10) + c->item = itOrbWinter; + if(orbChance(c, laCaves, 1200, 0) && items[itGold] >= 10) + c->item = itOrbDigging; + if(orbChance(c, laDryForest, 500, 2000) && items[itFernFlower] >= 10) + c->item = itOrbThorns; + + if(orbChance(c, laDeadCaves, 1800, 0) && items[itSilver] >= 10) + c->item = itGreenStone; + if(orbChance(c, laDeadCaves, 1800, 1000) && items[itSilver] >= 10) + c->item = itOrbDigging; + if(orbChance(c, laFjord, 1500, 2500) && items[itEmerald] >= 10) + c->item = itOrbPsi; + if(orbChance(c, laWineyard, 900, 1200) && items[itWine] >= 10) + c->item = itOrbGhost; + if(orbChance(c, laHive, 800, 1200) && items[itRoyalJelly] >= 10) + c->item = itOrbInvis; + if(orbChance(c, laPower, 0, 1500) && items[itPower] >= 10) + c->item = itOrbFire; + if(orbChance(c, laTemple, 0, 2500) && items[itGrimoire] >= 10) + c->item = itOrbDragon; + if(orbChance(c, laCamelot, 1000, 1500) && items[itHolyGrail]) + c->item = itOrbIllusion; + } + } + } + } + +// find worms and ivies +void settemp(cell *c) { + temps.push_back(c); tempval.push_back(c->monst); c->monst = moNone; + } + +void findWormIvy(cell *c) { + while(true) { + if(c->monst == moWorm || c->monst == moTentacle || c->monst == moWormwait || c->monst == moTentaclewait || + c->monst == moTentacleEscaping) { + worms.push_back(c); settemp(c); + break; + } + else if(c->monst == moWormtail) { + bool bug = true; + for(int i=0; itype; i++) { + cell* c2 = c->mov[i]; + if(c2 && isWorm(c2) && c2->mov[c2->mondir] == c) { + settemp(c); + c = c2; + bug = false; + } + } + if(bug) break; + } + else if(c->monst == moIvyWait) { + cell* c2 = c->mov[c->mondir]; + settemp(c); c=c2; + } + else if(c->monst == moIvyHead) { + ivies.push_back(c); settemp(c); + break; + } + else if(c->monst == moIvyBranch || c->monst == moIvyRoot) { + bool bug = true; + for(int i=0; itype; i++) { + cell* c2 = c->mov[i]; + if(c2 && (c2->monst == moIvyHead || c2->monst == moIvyBranch) && c2->mov[c2->mondir] == c) { + settemp(c); + c = c2; + bug = false; + } + } + if(bug) break; + } + else break; + } + } + +bool isGhostMover(eMonster m) { + return m == moGhost || m == moGreaterShark || + (cwt.c->land == laPower && (m == moWitchGhost || m == moWitchWinter)); + } + +bool havebugs, haveearth, haveeagles, haveleader; + +bool bugsfighting; + +// calculate cpdist and pathdist +void bfs() { + + int dcs = size(dcal); + for(int i=0; icpdist = INFD; + worms.clear(); ivies.clear(); ghosts.clear(); golems.clear(); mirrors.clear(); + temps.clear(); tempval.clear(); targets.clear(); havebugs = false; + haveearth = false; haveeagles = false; haveleader = false; + + dcal.clear(); dcal.push_back(cwt.c); + reachedfrom.clear(); reachedfrom.push_back(rand() % cwt.c->type); + + int pqs = size(pathq); + for(int i=0; ipathdist = INFD; + pathq.clear(); if(!invismove) targets.push_back(cwt.c); + + cwt.c->cpdist = 0; + int qb = 0; + while(true) { + int i, fd = reachedfrom[qb] + 3; + cell *c = dcal[qb++]; + int d = c->cpdist; + if(d == 7) { first7 = qb; break; } + for(int j=0; jtype; j++) if(i = (fd+j) % c->type, c->mov[i]) { + // printf("i=%d cd=%d\n", i, c->mov[i]->cpdist); + cell *c2 = c->mov[i]; + if(c2 && signed(c2->cpdist) > d+1) { + c2->cpdist = d+1; + + // remove treasures + if(c2->item && c2->cpdist == 7 && itemclass(c2->item) == IC_TREASURE && + items[c2->item] >= 20 + currentLocalTreasure) + c2->item = itNone; + + c2->ligon = 0; + dcal.push_back(c2); + reachedfrom.push_back(c->spn[i]); + if(c2->monst) { + if(isWorm(c2) || isIvy(c2)) findWormIvy(c2); + else if(isGhostMover(c2->monst)) + ghosts.push_back(c2); + else if(isBug(c2)) { + havebugs = true; + targets.push_back(c2); + } + else if(isFriendly(c2)) { + targets.push_back(c2); + if(c2->monst == moGolem) golems.push_back(c2); + if(c2->monst == moKnight) golems.push_back(c2); + if(c2->monst == moIllusion) { + if(items[itOrbIllusion]) items[itOrbIllusion]--; + else c2->monst = moNone; + } + if(isMimic(c2)) mirrors.push_back(c2); + } + else if(c2->monst == moEagle) haveeagles = true; + else if(c2->monst == moEarthElemental) haveearth = true; + else if(c2->monst == moCultistLeader) haveleader = true; + } + // pheromones! + if(c2->land == laHive && c2->heat >= 50 && c2->wall != waWaxWall) + havebugs = true; + if(c2->wall == waThumper && c2->tmp > 0) { + useup(c2); + targets.push_back(c2); + } + } + } + } + + for(int i=0; ipathdist = (targets[i] == cwt.c) ? 0 : 1; + pathq.push_back(targets[i]); + } + + int qtemp = size(temps); + for(int i=0; imonst = tempval[i]; + + pathqm.clear(); + reachedfrom.clear(); reachedfrom.push_back(rand() % cwt.c->type); + + qb = 0; + for(qb=0; qb < size(pathq); qb++) { + int fd = reachedfrom[qb] + 3; + cell *c = pathq[qb]; + eucoord x, y; + decodeMaster(c->master, x, y); + if(c->monst && !isBug(c) && !isFriendly(c)) { + pathqm.push_back(c); + continue; // no paths going through monsters + } + if(c->cpdist > 7) continue; + int d = c->pathdist; + for(int j=0; jtype; j++) { + int i = (fd+j) % c->type; + // printf("i=%d cd=%d\n", i, c->mov[i]->cpdist); + if(c->mov[i] && c->mov[i]->pathdist == INFD && !thruVine(c, c->mov[i]) && + (c->mov[i]->monst || passable(c->mov[i], (d==0)?NULL:c, true, false))) { + c->mov[i]->pathdist = d+1; + pathq.push_back(c->mov[i]); reachedfrom.push_back(c->spn[i]); + } + } + } + } + +extern void cleargraphmemory(); + +// initialize the game +void initgame() { + cwt.c = origin.c7; cwt.spin = 0; + cwt.c->land = euclid ? euclidland : firstland; + createMov(cwt.c, 0); + + for(int i=0; i<65536; i++) euland[i] = laNone; + + // extern int sightrange; sightrange = 9; + // cwt.c->land = laHell; items[itHell] = 10; + for(int i=9; i>=0; i--) { + setdist(cwt.c, i, NULL); + verifycells(&origin); + } + if(cwt.c->land == laCocytus) + cwt.c->wall = waFrozenLake; + else if(cwt.c->land == laAlchemist || cwt.c->land == laGameBoard) + ; + else if(cwt.c->land == laCaves || cwt.c->land == laFjord) + cwt.c->wall = waCavefloor; + else if(cwt.c->land == laDeadCaves) + cwt.c->wall = waDeadfloor2; + else + cwt.c->wall = waNone; + cwt.c->item = itNone; + cwt.c->monst = moNone; + + cleargraphmemory(); + + if(!safety) { + timerstart = time(NULL); turncount = 0; sagephase = 0; + timerstopped = false; + savecount = 0; savetime = 0; + cheater = 0; + if(firstland != laIce) cheater++; + } + else safety = false; + + // items[itGreenStone] = 100; + // items[itOrbTeleport] = 100; + + /* items[itGold] = 10; + items[itDiamond] = 10; + items[itSpice] = 10; + items[itElixir] = 10; + items[itRuby] = 10; + items[itShard] = 10; + items[itSilver] = 10; + items[itWine] = 10; + items[itRoyalJelly] = 10; + items[itEmerald] = 10; + items[itFeather] = 10; + kills[moYeti] = 90; */ + + /* + items[itGold] = 20; + items[itDiamond] = 20; + items[itSpice] = 20; + items[itRuby] = 20; + items[itElixir] = 20; + */ + + /* + items[itOrbShield] = 100; + items[itOrbSpeed] = 100; + items[itOrbWinter] = 100; + items[itOrbLightning] = 100; + */ + + // items[itOrbLightning] = 100; + // items[itRuby] = 100; + + // items[itOrbWinter] = 1000; + + bfs(); + } + +void firetrail(cell *c) { + if(!passable(c, NULL, true, true)) return; + destroyHalfvine(c); + c->item = itNone; + if(c->wall == waFrozenLake) + c->wall = waLake; + if(cellUnstableOrChasm(c)) + return; + c->wall = waBonfire, c->tmp = 10; + } + +void moveNormal(cell *c) { + bool repeat = true; + eMonster m = c->monst; + + again: + + for(int j=0; jtype; j++) + if(c->mov[j] && isFriendlyOrBug(c->mov[j]) && repeat && !attackingForbidden(c->mov[j], c)) { + // XLATC enemy destroys a friend + addMessage(XLAT("%The1 destroys %the2!", m, c->mov[j]->monst)); + c->mov[j]->monst = moNone; + return; + } + + int posdir[10], nc = 0; + + for(int j=0; jtype; j++) { + cell *c2 = c->mov[j]; + if(!c2) continue; + if(c2->pathdist >= c->pathdist) continue; + if(!passable(c2, c, false, false)) continue; + // crystal sages can't stand out of Cocytus + if(m == moCrystalSage && (c2->land != laCocytus || c2->heat > SAGEMELT)) + continue; + // lancers don't move next to other monsters + if(c->monst == moLancer) { + bool lancerok = true; + for(int u=2; u<=c2->type-2; u++) { + cell *c3 = c2->mov[(c->spn[j]+u)%c2->type]; + if(c3->monst && !isFriendlyOrBug(c3) && isKillableSomehow(c3)) + lancerok = false; + } + if(!lancerok) continue; + } + + +// if(m == moNecromancer ? c2->land == laGraveyard : true) +// it is more fun when demons step into the Land of Eternal Motion, IMO +// if((m == moLesser || m == moGreater) ? c2->land != laMotion : true) + if(c2->cpdist > 0) { + posdir[nc] = j; + nc++; + } + } + + if(nc == 0 && !passable(c, NULL, true, true)) { + // running dogs run away! + // they prefer a straight direction + int sgn = rand() % 2 ? 1 : -1; + for(int b=3; b>=0; b--) for(int s=-1; s<=1; s+=2) if(!nc) { + int d = (c->mondir + b*s*sgn) % c->type; + d += c->type; d %= c->type; + cell *c2 = c->mov[d]; + if(passable(c2, c, false, false)) + posdir[nc++] = d; + } + } + +/* + // Eagles can fly through chasms/slime if needed + if(m == moEagle && nc == 0) { + printf("no eagle no fly\n"); + for(int j=0; jtype; j++) printf("%d from %d\n", c->mov[j]->cpdist, c->cpdist); + for(int j=0; jtype; j++) + if(c->mov[j] && c->mov[j]->cpdist < c->cpdist && + !c->mov[j]->monst && + (c->mov[j]->land == laMotion || c->mov[j]->land == laAlchemist) && c->wall != waDeadTroll) + if(c->mov[j]->cpdist > 0) + posdest[nc++] = c->mov[j]; + printf("nc=%d\n", nc); + } */ + + if(!nc) return; + nc = rand() % nc; + cell *c2 = c->mov[posdir[nc]]; + c2->monst = m, c->monst = moNone; + c2->mondir = c->spn[posdir[nc]]; + if(m == moEagle && repeat && c->pathdist > 1) { repeat = false; c = c2; goto again; } + + // lancers pierce our friends :( + if(m == moLancer) { + // printf("lancer stab?\n"); + for(int u=2; u<=c2->type-2; u++) { + cell *c3 = c2->mov[(c->spn[posdir[nc]]+u)%c2->type]; + if(c3->monst && isKillableSomehow(c3)) { + addMessage(XLAT("%The1 pierces %the2!", m, c3->monst)); + killMonster(c3); + } + } + } + + if(m == moWitchFire) firetrail(c); + if(isWitch(m) && c2->item == itOrbLife && passable(c, NULL, true, true)) { + // note that Fire Witches don't pick up Orbs of Life, + addMessage(XLAT("%The1 picks up %the2!", moWitch, c2->item)); + c->monst = moEvilGolem; c2->item = itNone; + } + else if(m == moWitch) { + bool pickup = false; + if(c2->item == itOrbFlash) + pickup = true, m = moWitchFlash; + if(c2->item == itOrbWinter) + pickup = true, m = moWitchWinter; + if(c2->item == itOrbGhost) + pickup = true, m = moWitchGhost; + if(c2->item == itOrbFire) + pickup = true, m = moWitchFire; + // Orbs of Speed are a special case here, because we don't want + // the witch to move immediately + if(c2->item == itOrbLife) + pickup = true, c->monst = moEvilGolem; + if(pickup) { + addMessage(XLAT("%The1 picks up %the2!", moWitch, c2->item)); + c2->monst = m; c2->item = itNone; + } + } + } + +void explodeAround(cell *c) { + for(int j=0; jtype; j++) { + cell* c2 = c->mov[j]; + if(c2) { + if(isIcyLand(c2)) c2->heat += 0.5; + if((c2->wall == waDune || c2->wall == waIcewall || + c2->wall == waAncientGrave || c2->wall == waFreshGrave || + c2->wall == waColumn || c2->wall == waThumper || c2->wall == waBonfire || + c2->wall == waDryTree || c2->wall == waWetTree || + c2->wall == waVinePlant || c2->wall == waVineHalfA || c2->wall == waVineHalfB)) { + destroyHalfvine(c2); c2->wall = waNone; + } + if(c2->wall == waCavewall || c2->wall == waDeadTroll) c2->wall = waCavefloor; + if(c2->wall == waDeadfloor2) c2->wall = waDeadfloor; + if(c2->wall == waDeadwall) c2->wall = waDeadfloor2; + if(c2->wall == waBigStatue) c2->wall = waNone; + if(c2->wall == waFloorA || c2->wall == waFloorB) + if(c->wall == waFloorA || c->wall == waFloorB) + c2->wall = c->wall; + } + } + } + +void moveWorm(cell *c) { + + if(c->monst == moWormwait) { c->monst = moWorm; return; } + else if(c->monst == moTentaclewait) { c->monst = moTentacle; return; } + else if(c->monst == moTentacleEscaping) { + // explodeAround(c); + c->monst = moNone; + if(c->mondir != NODIR) c->mov[c->mondir]->monst = moTentacleEscaping; + return; + } + else if(c->monst != moWorm && c->monst != moTentacle) return; + + int ncg = 0, ncb = 0; + cell *gmov[7], *bmov[7]; + + int id = c->monst - moWorm; + + for(int j=0; jtype; j++) { + if(c->mov[j] && isFriendlyOrBug(c->mov[j]) && !attackingForbidden(c->mov[j], c)) { + addMessage(XLAT("%The1 eats %the2!", c->monst, c->mov[j]->monst)); + ncg = 1; gmov[0] = c->mov[j]; + break; + } + if(c->mov[j] && passable(c->mov[j], c, false, false) && !cellUnstable(c->mov[j]) && c->mov[j] != cwt.c) { + if(c->mov[j]->pathdist < c->pathdist) gmov[ncg++] = c->mov[j]; else bmov[ncb++] = c->mov[j]; + } + } + + if(ncg == 0 && ncb == 0) { + int spices = 0; + if(id) { + addMessage(XLAT("Cthulhu withdraws his tentacle!")); + kills[moTentacle]++; + c->monst = moTentacleEscaping; + moveWorm(c); + } + else { + addMessage(XLAT("The sandworm explodes in a cloud of Spice!")); + kills[moWorm]++; + spices = 3; + } + eItem loc = treasureType(c->land); + while(c->monst == moWorm || c->monst == moWormtail || c->monst == moTentacle || c->monst == moTentacletail) { + // if(!id) + explodeAround(c); + if(spices > 0 && c->land == laDesert) { + if(notDippingForExtra(itSpice, loc)) + c->item = itSpice; + spices--; + } + c->monst = moNone; + if(c->mondir != NODIR) c = c->mov[c->mondir]; + } + return; + } + + cell* goal; + if(ncg) goal = gmov[rand() % ncg]; + else goal = bmov[rand() % ncb]; + + for(int j=0; jtype; j++) if(c->mov[j] == goal) { + goal->monst = eMonster(moWormwait + id); + + c->monst = eMonster(moWormtail + id); + goal->mondir = c->spn[j]; + + if(id) break; + + cell *c2 = c, *c3 = c2; + for(int a=0; a<15; a++) + if(c2->monst == moWormtail) { + if(c2->mondir == NODIR) return; + c3 = c2, c2 = c3->mov[c2->mondir]; + } + + if(c2->monst == moWormtail) c2->monst = moNone, c3->mondir = NODIR; + } + + } + +void ivynext(cell *c) { + cellwalker cw(c, c->mondir); + cw.c->monst = moIvyWait; + bool findleaf = false; + while(true) { + cwspin(cw, 1); + if(cw.spin == signed(cw.c->mondir)) { + if(findleaf) { + cw.c->monst = moIvyHead; break; + } + cw.c->monst = moIvyWait; + cwstep(cw); + continue; + } + cwstep(cw); + if(cw.c->monst == moIvyWait && signed(cw.c->mondir) == cw.spin) { + cw.c->monst = moIvyBranch; + findleaf = true; continue; + } + cwstep(cw); + } + } + +// this removes Ivy, but also potentially causes Vines to grow +void removeIvy(cell *c) { + c->monst = moNone; + for(int i=0; itype; i++) + // note that semi-vines don't count + if(c->mov[i]->wall == waVinePlant) { + destroyHalfvine(c); + c->wall = waVinePlant; + } + } + +void moveivy() { + for(int i=0; imonst != moIvyHead) continue; + ivynext(c); + + cell *mto = NULL; + int pd = c->pathdist; + int sp = 0; + + while(c->monst != moIvyRoot) { + for(int j=0; jtype; j++) { + if(c->mov[j] && isFriendly(c->mov[j])) { + addMessage(XLAT("The ivy destroys %the1!", c->mov[j]->monst)); + c->mov[j]->monst = moNone; + continue; + } + if(c->mov[j] && signed(c->mov[j]->pathdist) < pd && passable(c->mov[j], c, false, false)) + mto = c->mov[j], pd = mto->pathdist, sp = c->spn[j]; + } + c = c->mov[c->mondir]; + } + + if(mto && mto->cpdist) { + mto->monst = moIvyWait, mto->mondir = sp; + // if this is the only branch, we want to move the head immediately to mto instead + if(mto->mov[mto->mondir]->monst == moIvyHead) { + mto->monst = moIvyHead; co->monst = moIvyBranch; + } + } + else if(co->mov[co->mondir]->monst != moIvyRoot) { + // shrink useless branches, but do not remove them completely (at the root) + if(co->monst == moIvyHead) co->mov[co->mondir]->monst = moIvyHead; + removeIvy(co); + } + } + } + +// move slimes, and also seeps + +int sval = 1; +vector slimedfs; + +bool isSlimeMover(cell *c) { + return + c->monst == moSlime || c->monst == moSeep || c->monst == moShark || + c->monst == moVineSpirit; + } + +void slimevisit(cell *c, cell *from, int u) { + if(!c) return; + if(eq(c->tmp, sval)) return; + if(c->wall != waCavewall && c->wall != waLake && c->wall != waDeadwall && + c->wall != waFloorA && c->wall != waFloorB && c->wall != waVinePlant && + c->wall != waVineHalfB && c->wall != waVineHalfA + ) return; + bool hv = false; + // cavewalls/deadwalls are the same for seeps + if(c->wall == waCavewall && from->wall == waDeadwall) hv++; + if(c->wall == waDeadwall && from->wall == waCavewall) hv++; + // only travel to halfvines correctly + if(cellHalfvine(c) && from != cwt.c) { + int i=0; + for(int t=0; ttype; t++) if(c->mov[t] && c->mov[t]->wall == c->wall) i=t; + int z = i-u; if(z<0) z=-z; z%=6; + if(z>1) return; + hv=true; + } + // only travel from halfvines correctly + if(cellHalfvine(from) && from != cwt.c) { + int i=0; + for(int t=0; ttype; t++) if(from->mov[t] && from->mov[t]->wall == from->wall) i=t; + int z = i-c->spn[u]; if(z<0) z=-z; z%=6; + if(z>1) return; + hv=true; + } + if(c->wall != from->wall && from != cwt.c && !hv) return; + if(c->item) return; + // if(c->wall == waThumper || c->wall == waBonfire) return; + c->tmp = sval; + if(size(slimedfs) < 1000) slimedfs.push_back(c), reachedfrom.push_back(u); + if(!isWorm(c) && !isIvy(c) && !isMimic(c)) + for(int i=0; itype; i++) if(c->mov[i] == from) + c->mondir = i; + if(isSlimeMover(c)) { + + for(int j=0; jtype; j++) + if(c->mov[j] && isFriendlyOrBug(c->mov[j])) { + // XLATC slime/seep/shark + addMessage(XLAT("%The1 eats %the2!", c->monst, c->mov[j]->monst)); + c->mov[j]->monst = moNone; + return; + } + + if(from->cpdist == 0 || from->monst) return; + + from->monst = c->monst, c->monst = moNone; + } + } + +void moveslimes() { + sval++; + slimedfs.clear(); reachedfrom.clear(); + for(int i=0; itype); + } + for(int i=0; itype; t++) { + int u = (j+t) % c->type; + slimevisit(c->mov[u], c, c->spn[u]); + } + } + } + +// move eagles + +vector eagledfs; + +void eaglevisit(cell *c, cell *from, int id) { + if(!c) return; + if(eq(c->tmp, sval)) return; + if(c->monst == moEagle) { + if(id == 1) for(int j=0; jtype; j++) + if(c->mov[j] && isFriendlyOrBug(c->mov[j]) && !attackingForbidden(c->mov[j], c)) { + // XLATC eagle + addMessage(XLAT("%The1 claws %the2!", c->monst, c->mov[j]->monst)); + c->mov[j]->monst = moNone; + return; + } + + if(from->cpdist == 0 || from->monst) return; + + from->monst = c->monst, c->monst = moNone; + } + if(c->wall == waThumper || isFire(c)) return; + c->tmp = sval; + if(!eaglepassable(c)) return; + if(size(eagledfs) < 1000) eagledfs.push_back(c); + } + +void moveeagles(int id) { + if(invismove) return; + sval++; + eagledfs.clear(); + for(int i=0; itype; t++) + eaglevisit(c->mov[t], c, id); + } + } + +vector earthdfs; + +bool earthpassable(cell *c, cell *from) { + // cannot go through Living Caves... + if(c->wall == waCavefloor) return false; + // but can dig through... + if(c->wall == waDeadwall || c->wall == waDune) + return true; + return passable(c, from, true, false); + } + +void earthMove(cell *from, int dir) { + cell *c2 = from->mov[dir]; + int d = from->spn[dir]; + earthWall(from); + if(c2) for(int u=2; u<=c2->type-2; u++) { + cell *c3 = c2->mov[(d + u)% c2->type]; + earthFloor(c3); + } + } + +void earthvisit(cell *c, cell *from, int d) { + if(!c) return; + if(eq(c->tmp, sval)) return; + + if(!earthpassable(c, from)) return; + + if(c->monst == moEarthElemental) { + // note: move from 'c' to 'from'! + for(int j=0; jtype; j++) + if(c->mov[j] && isFriendlyOrBug(c->mov[j]) && !attackingForbidden(c->mov[j], c)) { + // XLATC eagle + addMessage(XLAT("%The1 punches %the2!", c->monst, c->mov[j]->monst)); + c->mov[j]->monst = moNone; + return; + } + + if(!passable(from, c, false, false)) { + earthFloor(from); + return; + } + if(from->cpdist == 0 || from->monst) return; + + earthMove(c, from->spn[d]); + + from->monst = c->monst, c->monst = moNone; + } + if(c->wall == waThumper || isFire(c)) return; + c->tmp = sval; + if(size(earthdfs) < 1000) earthdfs.push_back(c); + } + +void moveearth() { + if(invismove) return; + sval++; + earthdfs.clear(); + for(int i=0; itype; t++) + earthvisit(c->mov[t], c, t); + } + } + +vector leaderdfs; + +bool canPushStatueOn(cell *c) { + return passable(c, NULL, true, false); + } + +// note: move from 'c' to 'from'! +void leadervisit(cell *c, cell *from, int d) { + if(!c) return; + if(eq(c->tmp, sval)) return; + + if(c->monst == moCultistLeader) { + // he cannot push big statues into bonfires, just like the player + if(c->wall == waBonfire && from->wall == waBigStatue) + return; + // note: move from 'c' to 'from'! + for(int j=0; jtype; j++) + if(c->mov[j] && isFriendlyOrBug(c->mov[j]) && !attackingForbidden(c->mov[j], c)) { + // XLATC eagle + addMessage(XLAT("%The1 punches %the2!", c->monst, c->mov[j]->monst)); + c->mov[j]->monst = moNone; + return; + } + + if(from->wall != waBigStatue && !passable(from, c, false, false)) { + return; + } + if(from->cpdist == 0 || from->monst) return; + + if(from->wall == waBigStatue) { + from->wall = c->wall; + c->wall = waBigStatue; + } + // earthMove(c, from->spn[d]); + + from->monst = c->monst, c->monst = moNone; + } + + else if(c->wall == waBigStatue ? !canPushStatueOn(from) : !passable(c, from, false, false)) + return; + + if(c->wall == waThumper || isFire(c)) return; + c->tmp = sval; + + if(size(leaderdfs) < 1000) leaderdfs.push_back(c); + } + +void moveleader() { + if(invismove) return; + sval++; + leaderdfs.clear(); + for(int i=0; itype; t++) + leadervisit(c->mov[t], c, t); + } + } + +#define SHSIZE 16 + +cell *shpos[SHSIZE]; +int cshpos = 0; + +void clearshadow() { + for(int i=0; imonst == moShadow) + shpos[cshpos]->monst = moNone; + shpos[cshpos] = cwt.c; + cshpos = (cshpos+1) % SHSIZE; + if(shpos[cshpos] && shpos[cshpos]->monst == moNone && shpos[cshpos]->cpdist && shpos[cshpos]->land == laGraveyard) + shpos[cshpos]->monst = moShadow; + } + +// from-to +bool ghostmove(cell* c1, cell* c2) { + if(c1->monst == moGhost || c1->monst == moWitchGhost) return true; + if(c1->monst == moGreaterShark) return c2->wall == waLake; + if(c1->monst == moWitchWinter) + return c2->wall == waBonfire || passable(c2, c1, false, false); + return false; + } + +void moveghosts() { + + if(invismove) return; + for(int d=0; d<8; d++) movesofgood[d].clear(); + + for(int i=0; imonst) && c->cpdist > 1) { + int goodmoves = 0; + + for(int k=0; ktype; k++) if(c->mov[k] && !c->mov[k]->monst && c->mov[k]->cpdist < c->cpdist) + if(ghostmove(c, c->mov[k])) + goodmoves++; + + movesofgood[goodmoves].push_back(c); + } + } + + for(int d=0; d<8; d++) for(int i=0; imonst) && c->cpdist > 1) { + + int mdir[7]; + + for(int j=0; jtype; j++) + if(c->mov[j] && isFriendlyOrBug(c->mov[j])) { + // XLATC ghost/greater shark + addMessage(XLAT("%The1 scares %the2!", c->monst, c->mov[j]->monst)); + c->mov[j]->monst = moNone; + return; + } + + int qmpos = 0; + for(int k=0; ktype; k++) if(c->mov[k] && !c->mov[k]->monst && c->mov[k]->cpdist < c->cpdist) + if(ghostmove(c, c->mov[k])) + mdir[qmpos++] = k; + if(!qmpos) continue; + int d = mdir[rand() % qmpos]; + cell *c2 = c->mov[d]; + c2->monst = c->monst; c->monst = moNone; + } + } + } + +int lastdouble = -3; + +void stabbingAttack(cell *mf, cell *mt, eMonster who = moNone) { + int numsh = 0, numflail = 0, numlance = 0; + for(int t=0; ttype; t++) { + cell *c = mf->mov[t]; + if(c->monst == moHedge || (!who && items[itOrbThorns] && c->monst && isKillable(c))) { + for(int u=0; utype; u++) { + if(c->mov[u] == mt) { + if(who) + addMessage(XLAT("%The1 stabs %the2.", who, c->monst)); + else + addMessage(XLAT("You stab %the1.", c->monst)); + int k = tkills(); + killMonster(c); + if(tkills() > k) numsh++; + } + } + } + if(c->monst == moFlailer) { + bool away = true; + for(int u=0; utype; u++) if(c->mov[u] == mt) away = false; + if(away) { + if(who) + addMessage(XLAT("%The1 tricks %the2.", who, c->monst)); + else + addMessage(XLAT("You trick %the1.", c->monst)); + int k = tkills(); + killMonster(c); + if(tkills() > k) numflail++; + } + } + } + + for(int t=0; ttype; t++) { + cell *c = mt->mov[t]; + if(c->monst == moLancer) { + if(who) + addMessage(XLAT("%The1 tricks %the2.", who, c->monst)); + else + addMessage(XLAT("You trick %the1.", c->monst)); + int k = tkills(); + killMonster(c); + if(tkills() > k) numlance++; + } + } + + if(numsh) achievement_count("STAB", numsh, 0); + + if(numlance && numflail && numsh) achievement_gain("MELEE3"); + + if(numlance + numflail + numsh >= 5) achievement_gain("MELEE5"); + + if(numsh == 2) { + if(lastdouble == turncount-1) achievement_count("STAB", 4, 0); + lastdouble = turncount; + } + } + +void movegolems() { + int qg = 0; + for(int i=0; imonst; + if(m == moGolem || m == moKnight) { + if(m == moGolem) qg++; + int bestv = 100, bq = 0, bdirs[7]; + for(int k=0; ktype; k++) if(c->mov[k]) { + int val; + if(c->mov[k] == cwt.c) val = 0; + else if(isActiveEnemy(c->mov[k], NULL) && isKillable(c->mov[k]) && + !attackingForbidden(c->mov[k], c)) + val = 12000; + else if(isInactiveEnemy(c->mov[k]) && isKillable(c->mov[k]) && + !attackingForbidden(c->mov[k], c)) + val = 10000; + else if(isIvy(c->mov[k]) && !attackingForbidden(c->mov[k], c)) val = 8000; + else if(monstersnear(c->mov[k], NULL, false)) val = 0; + else if(passable(c->mov[k], c, false, false)) val = 4000; + else val = 0; + if(c->monst == moGolem) + val -= c->mov[k]->cpdist; + if(c->monst == moKnight && c->mov[k]->master->alt) + val -= celldistAlt(c->mov[k]); + if(val > bestv) bestv = val, bq = 0; + if(val == bestv) bdirs[bq++] = k; + } + if(bestv <= 100) continue; + int dir = bdirs[rand() % bq]; + cell *c2 = c->mov[dir]; + if(c2->monst) { + addMessage(XLAT("%The1 destroys %the2!", c->monst, c2->monst)); + killMonster(c2); + } + else { + stabbingAttack(c, c2, m); + c2->monst = m == moGolem ? moGolemMoved : moKnightMoved; + c2->mondir = c->spn[dir]; + c->monst = moNone; + } + } + } + achievement_count("GOLEM", qg, 0); + } + +bool wchance(int a, int of) { + of *= 10; + a += items[itOrbYendor] * 5 + items[itHolyGrail] + 1; + if(cwt.c->land == laCrossroads) a+= items[itHyperstone] * 10; + for(int i=0; i 40) seepcount = (t-40 + rand() % 20) / 20; + int ghostcount = 0; + if(t > 80) ghostcount = (t-80 + rand() % 20) / 20; + + while(first7 < size(dcal)) { + int i = first7 + rand() % (size(dcal) - first7); + cell *c = dcal[i]; + + // wandering seeps & ghosts + if(seepcount && c->wall == waCavewall && !c->monst && eq(c->tmp, sval)) { + c->monst = moSeep; + seepcount--; + continue; + } + + if(ghostcount && !c->monst && cwt.c->type != laCaves) { + c->monst = moGhost; + ghostcount--; + continue; + } + + if((c->wall == waCavewall || c->wall == waDeadwall) && !c->monst && eq(c->tmp, sval) && + wchance(items[treasureType(c->land)], 10)) { + c->monst = moSeep; + continue; + } + + else if(c->monst || c->pathdist == INFD) break; + + else if(c->land == laIce && wchance(items[itDiamond], 10)) + c->monst = rand() % 2 ? moWolf : moYeti; + + else if(c->land == laDesert && wchance(items[itSpice], 10)) + c->monst = rand() % 10 ? moDesertman : moWorm; + + else if(c->land == laCaves && wchance(items[itGold], 5)) + c->monst = rand() % 3 ? moTroll : moGoblin; + + else if(c->land == laDeadCaves && wchance(items[itSilver], 5)) + c->monst = rand() % 20 ? (rand() % 3 ? moDarkTroll : moGoblin) : moEarthElemental; + + else if(c->land == laJungle && wchance(items[itRuby], 40)) + c->monst = rand() % 10 ? moMonkey : moEagle; + + else if(c->land == laMirror && wchance(items[itShard], 15)) + c->monst = rand() % 10 ? moRanger : moEagle; + + else if(c->land == laHell && wchance(items[itHell], 20)) + c->monst = rand() % 3 ? moLesser : moGreater; + + else if(c->land == laRlyeh && wchance(items[itStatue], 15)) + c->monst = rand() % 3 ? moPyroCultist : + (rand() % 40 < items[itStatue]-25) ? moCultistLeader : moCultist; + + else if(c->land == laGraveyard && wchance(items[itBone], 15)) + c->monst = rand() % 5 ? moGhost : moNecromancer; + + else if(c->land == laDryForest && wchance(items[itFernFlower], 5)) + c->monst = rand() % 5 ? moHedge : moFireFairy; + + else if(c->land == laCocytus && wchance(items[itSapphire], 45)) + c->monst = moCrystalSage; + + else if(c->land == laAlchemist && wchance(items[itElixir], 3) && eq(c->tmp, sval) && c->item == itNone) + c->monst = moSlime; + + else if(c->land == laFjord && wchance(items[itEmerald], 5)) { + static eMonster m[4] = {moHedge, moLancer, moMiner, moFlailer}; + c->monst = m[rand() % 4]; + } + + else if(c->land == laWineyard && wchance(items[itWine], 10)) { + c->monst = moVineBeast; + } + + else if(c->land == laPower && wchance(items[itPower], 10)) { + c->monst = eMonster(moWitch + rand() % NUMWITCH); + } + + else if(c->land == laCamelot && rand() % 30 == 0 && celldistAltRelative(c) < 0) { + eMonster m[3] = { moHedge, moLancer, moFlailer }; + c->monst = m[rand() % 3]; + } + + else if(c->land == laCrossroads && items[itHyperstone] && wchance(items[itHyperstone], 20)) { + // only interesting monsters here! + static eMonster m[12] = { + moWorm, moTroll, moEagle, + moLesser, moGreater, moPyroCultist, moGhost, + moFireFairy, moHedge, + moLancer, moFlailer, moVineBeast + }; + c->monst = m[rand() % 9]; + } + + else break; + + if(c->monst == moWorm) c->mondir = NODIR; + + // laMotion -> no respawn! + } + } + +void sageheat(cell *c, double v) { + c->heat += v; + if(c->wall == waFrozenLake && c->heat > .6) c->wall = waLake; + } + +bool normalMover(eMonster m) { + return + m == moYeti || m == moRanger || m == moGoblin || m == moTroll || m == moDesertman || + m == moMonkey || m == moZombie || m == moNecromancer || m == moCultist || + m == moLesser || m == moGreater || m == moRunDog || m == moPyroCultist || + m == moFireFairy || m == moCrystalSage || m == moHedge || + m == moVineBeast || m == moLancer || m == moFlailer || + m == moMiner || m == moDarkTroll || + (cwt.c->land == laPower && ( + (isWitch(m) && m != moWitchGhost && m != moWitchWinter) || m == moEvilGolem + )); + } + +struct buginfo_t { + cell *where; + short dist[BUGCOLORS]; + }; + +vector buginfo; + +vector bugqueue[BUGCOLORS]; +vector bugqueue4[BUGCOLORS]; + +struct bugtomove_t { + int dist, moves, index; + bugtomove_t(int d, int m, int i) { dist=d; moves=m; index=i; } + }; + +bool operator < (const bugtomove_t& m1, const bugtomove_t& m2) { + if(m1.dist != m2.dist) return m1.dist < m2.dist; + if(m1.moves != m2.moves) return m1.moves < m2.moves; + return false; + } + +vector bugtomove; +vector deadbug; +vector bugcellq; + +int bugcount[BUGCOLORS]; + +bool isBugEnemy(cell *c, int k) { + if(c == cwt.c && !invismove) return true; + if(!c->monst) return false; + if(c->monst == moBug0+k) return false; + if(isIvy(c)) return false; + return (isBug(c) || isKillableSomehow(c)); + } + +// list bugs and targets for each color +#define BUGINF 29999 + +void bugQueueInsert(int k, int i, int d) { + if(buginfo[i].dist[k] > d) { + if(buginfo[i].dist[k] != BUGINF) { + printf("%d -> %d\n", buginfo[i].dist[k], d); + } + buginfo[i].dist[k] = d; + bugqueue[k].push_back(i); + } + } + +void bugcell(cell *c) { + if(isActiv(c) || !passable(c, NULL, true, false)) + return; + short& i(c->tmp); + if(i >= 0 && i < size(buginfo) && buginfo[i].where == c) + return; + i = size(buginfo); + buginfo.resize(i+1); + buginfo_t& b(buginfo[i]); + b.where = c; + for(int k=0; ktype; dir++) { + cell *c2 = c->mov[dir]; + if(c2 && isBugEnemy(c2,k) && !attackingForbidden(c2, c)) { + if(isBug(c2)) havebug = true; + else haveother = true; + } + } + if(havebug) bugQueueInsert(k, i, 0); + else if(haveother) bugqueue4[k].push_back(i); + } +/*// bugs communicate if the distance is at most 2 + // also all nearby cells are inserted to the buginfo structure + if(size(buginfo) < 30000) { + for(int dir=0; dirtype; dir++) { + cell *c2 = c->mov[dir]; + if(c2) { + // if(isBug(c)) bugcellq.push_back(c2); => does not help... + for(int t=0; ttype; t++) + if(c2->mov[t] && isBug(c2->mov[t])) + bugcellq.push_back(c2), + bugcellq.push_back(c2->mov[t]); + } + } + }*/ + + // use pheromones! + if(c->land == laHive && c->heat > 1) { + c->heat -= 1; + for(int dir=0; dirtype; dir++) { + cell *c2 = c->mov[dir]; + if(c2) { + for(int t=0; ttype; t++) + if(c2->mov[t]) + bugcellq.push_back(c2), + bugcellq.push_back(c2->mov[t]); + } + } + } + } + +int last_d = -1; + +void handleBugQueue(int k, int t) { + int i = bugqueue[k][t]; + buginfo_t& b(buginfo[i]); + cell *c = b.where; + int d = b.dist[k]; + last_d = d; + int goodmoves = 0; + for(int dir=0; dirtype; dir++) { + cell *c2 = c->mov[dir]; + if(!c2) continue; + if(c2->tmp < 0 || c2->tmp >= size(buginfo)) continue; + if(!passable(c, c2, true, false)) continue; + int j = c2->tmp; + if(buginfo[j].where != c2) continue; + if(buginfo[j].dist[k] < d) goodmoves++; + bugQueueInsert(k, j, d+1); + } + if(isBug(c) && c->monst == moBug0+k) { + bugcount[c->monst - moBug0]++; + bugtomove.push_back(bugtomove_t(d,goodmoves,i)); + } + } + +#include + +void movebugs() { + buginfo.clear(); + for(int k=0; k check; + for(int t=0; tmonst; + int k = (m - moBug0) % BUGCOLORS; + int gmoves[8], q=0, bqual = -1; + + for(int dir=0; dirtype; dir++) { + cell *c2 = c->mov[dir]; + int qual = -10; + if(!c2) continue; + else if(isBugEnemy(c2, k) && c2->monst != moDeadBug) + qual = c2 != cwt.c ? 2 : -5; + else { + if(c2->monst) continue; + if(!passable(c2, c, false, false)) continue; + if(c2->tmp < 0 || c2->tmp >= size(buginfo)) continue; + if(buginfo[c2->tmp].where != c2) continue; + if(buginfo[c2->tmp].dist[k] < b.dist[k]) + qual = 1; + else if(buginfo[c2->tmp].dist[k] == b.dist[k]) + qual = 0; + } + // printf("%d->#%d %d: %d\n", i, dir, c2->tmp, qual); + if(qual > bqual) bqual = qual, q=0; + if(qual == bqual) gmoves[q++] = dir; + } + + if(!q) { c->heat += 3; continue; } + int d = gmoves[rand() % q]; + cell *c2 = c->mov[d]; + if(c2->monst) { + eMonster killed = c2->monst; + if(isBug(killed)) battlecount++; + else addMessage(XLAT("%The1 fights with %the2!", c->monst, c2->monst)); + killMonster(c2); + // killMonster(c); + if(isBug(killed)) { + c2->monst = moDeadBug, deadbug.push_back(c2); + bugcount[killed - moBug0]--; + } +// c->monst = moDeadBug, deadbug.push_back(c); + } + else { + c2->monst = c->monst; + c2->mondir = c->spn[d]; + c->monst = moNone; + // pheromones! + if(c->heat < 90) c->heat += 5; + if(c2->heat < 90) c2->heat += 5; + // if(isHive(c2->land)) c2->land = eLand(laHive0+k); +/* if(c2->item == itRoyalJelly && !isQueen(m)) { + // advance! + c2->monst = eMonster(m+BUGCOLORS); + c2->item = itNone; + } */ + } + } + + // cleanup + for(int i=0; imonst = moNone; + if(battlecount) + addMessage(XLAT("The Hyperbugs are fighting!")); + + int maxbug = 0; + for(int k=0; k maxbug) maxbug = bugcount[k]; + + achievement_count("BUG", maxbug, 0); + } + +void bugcitycell(cell *c, int d) { + if(isActiv(c) || !passable(c, NULL, true, false)) return; + short& i = c->tmp; + if(i >= 0 && i < size(buginfo) && buginfo[i].where == c) + return; + i = size(buginfo); + buginfo_t b; + b.where = c; + b.dist[0] = d; + buginfo.push_back(b); + } + +void createBugArmy(cell *c) { + int k = rand() % BUGCOLORS; + int minbugs = 50, maxbugs = 50; + int var = 5 + items[itRoyalJelly]; + if(var>25) var=25; + // minbugs += 100; maxbugs += 100; + minbugs -= var; maxbugs += var; + maxbugs += items[itRoyalJelly]; + int numbugs = minbugs + rand() % (maxbugs - minbugs + 1); + + /* int i = items[itRoyalJelly]; + int chance = 20 + 25 * i + 9000; + // i=0: 16% + // i=10: 73% + // i=50: 1270 vs 6000 + eMonster m = eMonster(moBug0 + rand() % BUGCOLORS); + if(c->wall) return; + for(int i=0; itype; i++) { + cell *c2 = createMov(c,i); + if(rand() % (100+chance) < chance) { + if(!c2->wall) c2->monst = m; + for(int j=2; j<=c2->type-2; j++) { + int jj = (j+c->spn[i]) % c2->type; + cell *c3 = createMov(c2, jj); + if(rand() % (6000+chance) < chance && !c3->wall) + c3->monst = m; + } + } + } + c->monst = eMonster(m + BUGCOLORS); */ + + int gdir = -1; + for(int i=0; itype; i++) { + if(c->mov[i] && c->mov[i]->mpdist < c->mpdist) gdir = i; + } + if(!gdir) return; + cellwalker bf(c, gdir); + for(int i=0; i<7; i++) { + if(bf.c->type == 6) + cwspin(bf, 3); + else + cwspin(bf, 3 + rand() % 2); + cwstep(bf); + } + cell *citycenter = bf.c; + buginfo.clear(); + + // mark the area with BFS + bugcitycell(citycenter, 0); + for(int i=0; iland != laHive && c->land != laNone) return; + if(c->bardir != NODIR) return; + if(c->heat >= 100) return; + // bfs + if(d < 9) for(int t=0; ttype; t++) + bugcitycell(createMov(c,t), d+1); + } + + // place everything + for(int i=0; iwall == waNone) + c->item = itRoyalJelly; + c->bardir = NOBARRIERS; + if(d == 9 || d == 6 || d == 3) + c->barleft = eLand(d/3), + c->barright = eLand(k); + else + c->barleft = laNone; + if(numbugs && c->wall == waNone) + c->monst = eMonster(moBug0 + k), numbugs--; + c->land = laHive; + // prevent barriers + if(c->mpdist == INFD) c->mpdist = BUGLEV; + } + } + +void moveFastMonsters() { + for(int i=0; imonst == moWitchSpeed) { + + if(c->pathdist == 1 && c->monst != moGhost) { + if(items[itOrbShield]) continue; + addMessage(XLAT("%The1 is confused!", c->monst)); + break; + } + + int goodmoves = 0; + for(int t=0; ttype; t++) { + cell *c2 = c->mov[t]; + if(c2 && c2->pathdist < c->pathdist) + goodmoves++; + } + movesofgood[goodmoves].push_back(c); + } + } + + for(int d=0; d<8; d++) for(int i=0; imonst != moNone) + moveNormal(c); + } + } + +void activateFlashFrom(cell *cf); + +vector nonmovers; + +bool sagefresh = true; + +void considerEnemyMove(cell *c) { + eMonster m = c->monst; + + if(isActiveEnemy(c, NULL)) { + + if(c->pathdist == 1 && c->monst != moGhost) { + // c->iswall = true; c->ismon = false; + if(items[itOrbShield] || c->monst == moCrystalSage) return; + + addMessage(XLAT("%The1 is confused!", m)); + // playerdead = true; + return; + } + + if(c->monst == moWitch && c->item == itOrbSpeed) { + addMessage(XLAT("%The1 picks up %the2!", moWitch, c->item)); + c->monst = moWitchSpeed; c->item = itNone; + } + + if(c->monst == moNecromancer) { + int gravenum = 0, zombienum = 0; + cell *gtab[8], *ztab[8]; + for(int j=0; jtype; j++) if(c->mov[j]) { + if(c->mov[j]->wall == waFreshGrave) gtab[gravenum++] = c->mov[j]; + if(passable(c->mov[j], c, false, false) && c->mov[j]->pathdist < c->pathdist) + ztab[zombienum++] = c->mov[j]; + } + if(gravenum && zombienum) { + cell *gr = gtab[rand() % gravenum]; + gr->wall = waAncientGrave; + gr->monst = moGhost; + ztab[rand() % zombienum]->monst = moZombie; + addMessage(XLAT("%The1 raises some undead!", c->monst)); + return; + } + } + + if(c->monst == moWolf) { + int bhd = NODIR; + ld besth = c->heat; + for(int j=0; jtype; j++) if(c->mov[j]->heat > besth && passable(c->mov[j], c, false, false)) + besth = c->mov[j]->heat, bhd = j; + if(bhd != NODIR) { + // printf("wolf moved from %Lf (%p) to %Lf (%p)\n", c->heat, c, besth, c->mov[bhd]); + c->mov[bhd]->monst = moWolfMoved, c->monst = moNone; + } + } + + else if(c->monst == moPyroCultist && c->cpdist <= 4 && cwt.c->wall == waNone && !cellUnstable(cwt.c)) { + addMessage(XLAT("%The1 throws fire at you!", c->monst)); + if(itemBurns(cwt.c->item)) + addMessage(XLAT("%The1 burns!", cwt.c->item)), cwt.c->item = itNone; + cwt.c->wall = waBonfire; + cwt.c->tmp = 20; + c->monst = moCultist; + } + + else if(c->monst == moWitchFlash && flashWouldKill(c, true) && !flashWouldKill(c, false)) { + addMessage(XLAT("%The1 activates her Flash spell!", c->monst)); + c->monst = moWitch; + activateFlashFrom(c); + } + + else if(c->monst == moCrystalSage && c->cpdist <= 4 && isIcyLand(cwt.c)) { + // only one sage attacks + if(sagefresh) { + sagefresh = false; + if(sagephase == 0) { + addMessage(XLAT("%The1 shows you two fingers.", c->monst)); + addMessage(XLAT("You wonder what does it mean?")); + } + else if(sagephase == 1) { + addMessage(XLAT("%The1 shows you a finger.", c->monst)); + addMessage(XLAT("You think about possible meanings.")); + } + else { + addMessage(XLAT("%The1 moves his finger downwards.", c->monst)); + addMessage(XLAT("Your brain is steaming.")); + } + sagephase++; + sageheat(cwt.c, .0); + for(int i=0; itype; i++) + sageheat(cwt.c->mov[i], .3); + } + } + + else if(normalMover(m)) { + int goodmoves = 0; + for(int t=0; ttype; t++) { + cell *c2 = c->mov[t]; + if(c2 && c2->pathdist < c->pathdist) + goodmoves++; + } + movesofgood[goodmoves].push_back(c); + } + } + } + +void movemonsters() { + + sagefresh = true; + turncount++; + + DEBT("ghosts"); + moveghosts(); + + DEBT("normal"); + + for(int d=0; d<8; d++) movesofgood[d].clear(); + + for(int i=0; ipathdist == INFD) + considerEnemyMove(c); + } + + for(int d=0; d<8; d++) for(int i=0; imonst)) + moveNormal(c); + } + + if(sagefresh) sagephase = 0; + + DEBT("worm"); + int wrm = size(worms); + for(int i=0; imonst == moWolfMoved) c->monst = moWolf; + if(c->monst == moIvyNext) { + c->monst = moIvyHead; ivynext(c); + } + if(c->monst == moIvyDead) + removeIvy(c); + if(c->monst == moGolemMoved) c->monst = moGolem; + if(c->monst == moKnightMoved) c->monst = moKnight; + if(c->monst == moSlimeNextTurn) c->monst = moSlime; + if(c->monst == moLesser) c->monst = moLesserM; + else if(c->monst == moLesserM) c->monst = moLesser; + if(c->monst == moGreater) c->monst = moGreaterM; + else if(c->monst == moGreaterM) c->monst = moGreater; + + if(c->wall == waChasm) { + c->item = itNone; + if(c->monst && c->monst != moGhost && c->monst != moEagle) { + if(c->monst != moRunDog) achievement_gain("FALLDEATH1"); + killMonster(c); + } + } + + if(c->wall == waBonfire) { + if(c->monst && c->monst != moGhost && c->monst != moWitchWinter && c->monst != moWitchGhost) { + addMessage(XLAT("%The1 burns!", c->monst)); + killMonster(c); + } + } + + if(c->wall == waLake) { + c->item = itNone; + if(c->monst == moLesser || c->monst == moLesserM || c->monst == moGreater || c->monst == moGreaterM) + c->monst = moGreaterShark; + if(c->monst && c->monst != moShark && c->monst != moGreaterShark && + c->monst != moGhost && c->monst != moEagle) killMonster(c); + } + + if(c->monst && cellUnstable(c) && c->monst != moGhost && c->monst != moEagle) { + c->wall = waChasm; + } + } + + DEBT("shadow"); + moveshadow(); + + DEBT("wandering"); + wandering(); + } + +// move heat + +vector vinefires; + +void heat() { + double rate = items[itOrbSpeed] ? .5 : 1; + int oldmelt = kills[0]; + + /* if(cwt.c->heat > .5) cwt.c->heat += .3; + if(cwt.c->heat > 1.) cwt.c->heat += .3; + if(cwt.c->heat > 1.4) cwt.c->heat += .5; */ + if(isIcyLand(cwt.c)) + cwt.c->heat += (items[itOrbWinter] ? -1.2 : 1.2) * rate; + + vinefires.clear(); + + int dcs = size(dcal); + for(int i=0; icpdist > 8) break; + if(isFire(c) && c->tmp > 0) { + if(c->land != laPower) useup(c); + if(c->wall == waBonfire) for(int i=0; itype; i++) { + cell *c2 = c->mov[i]; + if(c2 && c2->wall == waVinePlant) + vinefires.push_back(c2); + // both halfvines have to be near fire at once + if(c2 && cellHalfvine(c2) && c->mov[(i+1)%c->type]->wall == c2->wall) + vinefires.push_back(c2); + } + + // two semifires are required to spread + if(c->wall == waPartialFire) for(int i=0; itype; i++) { + cell *c2 = c->mov[i]; + if(c2 && (c2->wall == waVinePlant)) { + for(int j=0; jtype; j++) if(c2->mov[j] && c2->mov[j]->wall == waPartialFire && + c2->mov[j] != c) + vinefires.push_back(c2); + } + } + } + if(!isIcyLand(c)) continue; + if(c->monst == moRanger) c->heat += 3 * rate; + if(c->monst == moDesertman) c->heat += 4 * rate; + if(c->monst == moMonkey) c->heat += rate; + if(c->wall == waDeadTroll) c->heat -= 2 * rate; + if(c->wall == waBigStatue) c->heat -= 3 * rate; + if(c->monst == moLesser || c->monst == moLesserM || c->monst == moGreater || c->monst == moGreaterM) + c->heat += (c->land == laCocytus ? 1.5 : 10) * rate; + if(c->monst == moGreaterShark) + c->heat += 2 * rate; + if(c->monst == moCultist) c->heat += 3 * rate; + if(c->monst == moCultistLeader) c->heat += 4 * rate; + if(c->monst == moPyroCultist) c->heat += 6 * rate; + if(c->monst == moGhost) c->heat -= rate; + if(c->wall == waBonfire && c->tmp > 0) c->heat += 4 * rate; + + ld hmod = 0; + + for(int j=0; jtype; j++) if(c->mov[j]) { + if(!isIcyLand(c->mov[j])) { + // make sure that we can still enter Cocytus, + // it won't heat up right away even without Orb of Winter or Orb of Speed + if(c->mov[j] == cwt.c && (c->land == laIce || items[itOrbWinter])) + hmod += rate * (items[itOrbWinter] ? -1.2 : 1.2) / 4; + continue; + } + ld hdiff = c->mov[j]->heat - c->heat; + hdiff /= 10; + if(c->mov[j]->cpdist <= 8) + c->mov[j]->heat -= hdiff; + else + hdiff = -c->heat / 250; + hmod += hdiff; + } + + c->heat += hmod * rate; + if(c->monst == moCrystalSage && c->heat >= SAGEMELT) { + addMessage(XLAT("%The1 melts away!", c->monst)); + killMonster(c); + } + } + + for(int i=0; iwall == waIcewall && c->heat > .4) c->wall = waNone, kills[0]++; + if(c->wall == waFrozenLake && c->heat > .6) c->wall = waLake, kills[0]++; + if(c->wall == waLake && c->heat < -.4 && c->monst != moGreaterShark) { + c->wall = waFrozenLake; + if(c->monst == moShark) { + addMessage(XLAT("%The1 is frozen!", c->monst)); + killMonster(c); + } + } + } + + for(int i=0; iwall == waVinePlant) { + if(c->monst == moVineBeast) killMonster(c); + c->wall = waBonfire, c->tmp = 6; + } + else if(cellHalfvine(c)) destroyHalfvine(c, waPartialFire); + } + + if(kills[0] != oldmelt) bfs(); + } + +bool gardener = false; + +void livecaves() { + int dcs = size(dcal); + + vector bringlife; + + for(int i=0; icpdist > 8) break; + + if(c->wall != waCavefloor && c->wall != waCavewall) continue; + + // if(c->wall == waThumper || c->wall == waBonfire) continue; + c->tmp = 0; + if(c->monst == moDarkTroll) c->monst = moTroll; + if(c->item || c->monst || c->cpdist == 0) continue; + for(int j=0; jtype; j++) if(c->mov[j]) { + if(c->mov[j]->wall == waDeadfloor) c->tmp++, bringlife.push_back(c->mov[j]); + else if(c->mov[j]->wall == waDeadwall || c->mov[j]->wall == waDeadfloor2) c->tmp--, bringlife.push_back(c->mov[j]); + else if(c->mov[j]->wall == waCavefloor) c->tmp++; + else if(c->mov[j]->wall == waCavewall) c->tmp--; + else if(c->mov[j]->wall == waDeadTroll) c->tmp -= 5; + else if(c->mov[j]->wall == waVinePlant) c->tmp--; + else if(c->mov[j]->wall != waBarrier) c->tmp += 5; + if(c->mov[j]->cpdist == 0 && items[itOrbDigging]) c->tmp+=100; + if(c->mov[j]->wall == waThumper && c->mov[j]->tmp > 0) c->tmp+=100; + if(c->mov[j]->wall == waBonfire) c->tmp+=100; + if(c->mov[j]->wall == waBigStatue) c->tmp-=100; + if(c->mov[j]->item) c->tmp+=2; + if(c->mov[j]->monst == moZombie) c->tmp += 10; + if(c->mov[j]->monst == moGhost) c->tmp += 10; + if(c->mov[j]->monst == moNecromancer) c->tmp += 10; + if(c->mov[j]->monst == moWormtail) c->tmp++; + if(c->mov[j]->monst == moTentacletail) c->tmp-=2; + if(isIvy(c->mov[j])) c->tmp--; + if(isDemon(c->mov[j])) c->tmp-=3; + // if(c->mov[j]->monst) c->tmp++; + // if(c->mov[j]->monst == moTroll) c->tmp -= 3; + } + } + + for(int i=0; icpdist > 8) break; + if(c->wall != waCavefloor && c->wall != waCavewall) continue; +// if(c->land != laCaves) continue; +// if(c->wall == waThumper || c->wall == waBonfire) continue; + + if(c->tmp > 0) c->wall = waCavefloor; + if(c->tmp < 0) { + c->wall = waCavewall; + if(c->land != laCaves && c->land != laDeadCaves && c->land != laFjord && !gardener) { + gardener = true; + achievement_gain("GARDENER"); + } + } + } + + for(int i=0; iwall == waDeadfloor) c->wall = waCavefloor; + if(c->wall == waDeadfloor2) c->wall = waCavewall; + if(c->wall == waDeadwall) c->wall = waCavewall; + if(c->wall == waCavewall && c->item) c->wall = waCavefloor; + if(c->land == laDeadCaves) c->land = laCaves; + if(c->item == itSilver) c->item = itGold; + if(c->item == itGreenStone) c->item = itOrbLife; + if(c->monst == moEarthElemental) { + addMessage(XLAT("%The1 is destroyed by the forces of Life!", c->monst)); + killMonster(c); + c->item = itOrbDigging; + } + } + } + +void dryforest() { + int dcs = size(dcal); + for(int i=0; icpdist > 8) break; + if(c->land != laDryForest) continue; + if(c->wall == waThumper) continue; + if(c->wall == waBonfire) + c->heat = 0; + + for(int j=0; jtype; j++) if(c->mov[j]) { + if(c->mov[j]->wall == waBonfire) c->heat++; + } + } + + for(int i=0; icpdist > 8) break; + if(c->land != laDryForest) continue; + if(c->wall == waNone && c->heat >= 10) + burnMonstersAndItems(c, 50); + if((c->wall == waDryTree || c->wall == waWetTree || c->wall == waBonfire) && c->heat >= 1) + c->wall = waBonfire, c->tmp = 50; + } + +/* + for(int i=0; itmp = 0; + c->heat = 0; + if(c->cpdist > 8) break; + if(c->land != laDryForest) continue; + + for(int j=0; jtype; j++) if(c->mov[j]) { + if(c->mov[j]->wall == waWetTree) + c->tmp++; + if(c->mov[j]->wall == waDryTree) + c->heat++; + } + } + + for(int i=0; itype - c->tmp - int(c->heat); + if(c->tmp > a && c->tmp > c->heat) + c->wall = waWetTree; + else if(c->heat > a && c->heat > c->tmp) + c->wall = waDryTree; + else if(a > c->heat && a > c->tmp) + c->wall = waNone; + } */ + } + +// mirror management + +bool cellMirrorable(cell *c) { + return + c->wall == waNone || c->wall == waCavefloor || c->wall == waFloorA || c->wall == waFloorB || + c->wall == waFrozenLake || c->wall == waDeadfloor || c->wall == waDeadfloor2; + } + +void castLightningBolt(cellwalker lig); + +void createMM(cellwalker& cw, eMonster type) { + if(type == moLightningBolt) + castLightningBolt(cw); + else if(cw.c->monst == moNone && cellMirrorable(cw.c) && cw.c != cwt.c) { + cw.c->monst = type; + cw.c->mondir = cw.spin; + } + } + +void createMirrors(cell *c, int dir, eMonster type) { + cellwalker C(c, dir); + + if(type == moMirror) type = moMirage; + else if(type == moMirage) type = moMirror; + + for(int i=0; i<6; i++) { + cwstep(C); + if(C.c->type == 6) { + cwspin(C, i); + createMM(C, type); + cwspin(C, -i); + } + cwstep(C); + cwspin(C, 1); + } + } + +void createMirages(cell *c, int dir, eMonster type) { + cellwalker C(c, dir); + for(int i=0; i<6; i++) { + cwstep(C); + if(C.c->type == 6) { + cwspin(C, 2); + cwstep(C); + cwspin(C, 4-i); + createMM(C, type); + cwspin(C, 6-4+i); + cwstep(C); + cwspin(C, 2); + cwstep(C); + cwspin(C, 2-i); + createMM(C, type); + cwspin(C, 6-2+i); + cwstep(C); + cwspin(C, 2); + } + cwstep(C); + cwspin(C, 1); + } + } + +void spinmirrors(int d) { + + for(int i=0; imonst == moMirror) + mirrors[i]->mondir = (mirrors[i]->mondir - d + 42) % mirrors[i]->type; + if(c->monst == moMirage) + mirrors[i]->mondir = (mirrors[i]->mondir + d + 42) % mirrors[i]->type; + } + + } + +void destroyMirrors() { + for(int i=0; imonst; + if(isMimic(m)) c->monst = moNone; + } + mirrors.clear(); + } + +void destroyStrayMirrors() { + for(int i=0; icpdist > 7 && isMimic(c)) { + c->monst = moNone; + } + } + } + +void gomirrors(bool go) { + int tk = tkills(); + int nummirage = 0; + mirrors2.clear(); + for(int i=0; imonst; + if(isMimic(m)) { + if(m == moMirage) nummirage++; + cell *c2 = c->mov[c->mondir]; + if(c2 && c2->monst != moNone && !isMimic(c2) && isKillable(c2)) { + addMessage(XLAT("%The1 destroys %the2!", m, c2->monst)); + killMonster(c2); + } + if(!go) continue; + c->monst = moNone; + if(!c2) continue; + stabbingAttack(c, c2, m); + if(!passable(c2, c, true, true)) continue; + if(isWorm(c2)) continue; + if(c2->monst == moGreater) { + c2->monst = moLesser; continue; + } + if(c2->monst == moGreaterM) { + c2->monst = moLesserM; continue; + } + if(c2 == cwt.c) { + addMessage(XLAT("You join %the1.", m)); + continue; + } + if(isMimic(c2)) { + addMessage(XLAT("Two of your images crash and disappear!")); + c2->monst = moNone; + continue; + } + if(isIvy(c2)) { + // killIvy(c2); + continue; + } + c2->monst = m; + c2->mondir = c->spn[c->mondir]; + mirrors2.push_back(c2); + } + } + for(int i=0; imonst; + if(c->wall == waMirror) { + addMessage(XLAT("%The1 breaks the mirror!", m)); + createMirrors(c, c->mondir, m); + c->wall = waNone; + } + if(c->wall == waCloud) { + addMessage(XLAT("%The1 disperses the cloud!", m)); + createMirages(c, c->mondir, m); + c->wall = waNone; + } + } + achievement_count("MIRRORKILL", tkills(), tk); + achievement_count("MIRAGE", nummirage, 0); + } + +void reduceOrbPowers() { + if(items[itOrbLightning]) items[itOrbLightning]--; + if(items[itOrbSpeed]) items[itOrbSpeed]--; + if(items[itOrbFlash]) items[itOrbFlash]--; + if(items[itOrbShield]) items[itOrbShield]--; + if(items[itOrbWinter]) items[itOrbWinter]--; + if(items[itOrbFire]) items[itOrbFire]--; + if(items[itOrbIllusion]) items[itOrbIllusion]--; + if(items[itOrbDragon]) items[itOrbDragon]--; + if(items[itOrbPsi]) items[itOrbPsi]--; + if(items[itOrbInvis]) items[itOrbInvis]--; + if(items[itOrbGhost]) items[itOrbGhost]--; + if(items[itOrbDigging]) items[itOrbDigging]--; + if(items[itOrbTeleport]) items[itOrbTeleport]--; + if(items[itOrbSafety]) items[itOrbSafety]--; + if(items[itOrbThorns]) items[itOrbThorns]--; + } + +void flashAlchemist(cell *c) { + if(c->wall == waFloorA || c->wall == waFloorB) { + if(cwt.c->wall == waFloorA || cwt.c->wall == waFloorB) + c->wall = cwt.c->wall; + else + c->wall = eWall(c->wall ^ waFloorB ^ waFloorA); + } + } + +void flashCell(cell *c, bool msg) { + flashAlchemist(c); + if(msg && c->monst && !isWorm(c) && c->monst != moShadow) + addMessage(XLAT("%The1 is destroyed by the Flash.", c->monst)); + killMonster(c); + if(isIcyLand(c)) + c->heat += 2; + if(c->land == laDryForest) + c->heat += 2; + if(c->wall == waCavewall) c->wall = waCavefloor; + if(c->wall == waDeadTroll) c->wall = waCavefloor; + if(c->wall == waDeadfloor2) c->wall = waDeadfloor; + if(c->wall == waDeadwall) c->wall = waDeadfloor2; + if(c->wall == waMirror) c->wall = waNone; + if(c->wall == waCloud) c->wall = waNone; + if(c->wall == waDune) c->wall = waNone; + if(c->wall == waAncientGrave) c->wall = waNone; + if(c->wall == waFreshGrave) c->wall = waNone; + if(c->wall == waColumn) c->wall = waNone; + if(c->wall == waGlass) c->wall = waNone; + if(c->wall == waDryTree || c->wall == waWetTree) c->wall = waNone; + if(c->wall == waBigStatue) c->wall = waNone; + if(isActiv(c)) c->tmp = 77; + } + +extern void drawFlash(cell* c); + +void activateFlashFrom(cell *cf) { + drawFlash(cf); + for(int i=0; itype; t++) + for(int u=0; utype; u++) + if(c->mov[t] == cf->mov[u] && c->mov[t] != NULL) { + flashCell(c, true); + } + } + } + +void activateFlash() { + int tk = tkills(); + drawFlash(cwt.c); + addMessage(XLAT("You activate the Flash spell!")); + items[itOrbFlash] = 0; + for(int i=0; icpdist > 2) break; + flashCell(c, false); + } + achievement_count("FLASH", tkills(), tk); + } + +bool barrierAt(cellwalker& c, int d) { + if(d >= 7) return true; + if(d <= -7) return true; + d = c.spin + d + 42; + d%=c.c->type; + if(!c.c->mov[d]) return true; + if(c.c->mov[d]->wall == waBarrier) return true; + return false; + } + +void castLightningBolt(cellwalker lig) { + int bnc = 0; + while(true) { + // printf("at: %p i=%d d=%d\n", lig.c, i, lig.spin); + if(lig.c->mov[lig.spin] == 0) break; + cwstep(lig); + + cell *c = lig.c; + + flashAlchemist(c); + killMonster(c); + if(isIcyLand(c) || c->land == laDryForest) c->heat += 2; + c->ligon = 1; + + bool brk = false, spin = false; + + if(c->wall == waCavewall) c->wall = waCavefloor, brk = true; + if(c->wall == waDeadTroll) c->wall = waCavefloor, brk = true; + if(c->wall == waDeadfloor2)c->wall = waDeadfloor; + if(c->wall == waDeadwall) c->wall = waDeadfloor2, brk = true; + if(c->wall == waGlass) c->wall = waNone, spin = true; + if(c->wall == waDune) c->wall = waNone, brk = true; + if(c->wall == waIcewall) c->wall = waNone, brk = true; + if(c->wall == waAncientGrave) c->wall = waNone, spin = true; + if(c->wall == waFreshGrave) c->wall = waNone, spin = true; + if(c->wall == waBigStatue) c->wall = waNone, spin = true; + if(c->wall == waColumn) c->wall = waNone, spin = true; + if(isActiv(c)) c->tmp = 77; + if(c->wall == waDryTree || c->wall == waWetTree || c->wall == waVinePlant) { + burnMonstersAndItems(c, 4); + brk = true; + } + if(cellHalfvine(c) && c->mov[lig.spin] && c->wall == c->mov[lig.spin]->wall) { + destroyHalfvine(c, waPartialFire, 4); + brk = true; + } + + if(c == cwt.c) {bnc++; if(bnc > 10) break; } + if(spin) cwspin(lig, rand() % lig.c->type); + + if(brk) break; + + if(c->wall == waBarrier || c->wall == waCamelot) { + int left = -1; + int right = 1; + while(barrierAt(lig, left)) left--; + while(barrierAt(lig, right)) right++; + cwspin(lig, -(right + left)); + bnc++; if(bnc > 10) break; + } + else { + cwspin(lig, 3); + if(c->type == 7) cwspin(lig, rand() % 2); + } + + if(c->wall == waCloud) { + c->wall = waNone; + createMirages(c, lig.spin, moLightningBolt); + } + + if(c->wall == waMirror) { + c->wall = waNone; + createMirrors(c, lig.spin, moLightningBolt); + break; + } + } + } + +void activateLightning() { + int tk = tkills(); + extern void drawLightning(); + drawLightning(); + addMessage(XLAT("You activate the Lightning spell!")); + items[itOrbLightning] = 0; + for(int i=0; itype; i++) + castLightningBolt(cellwalker(cwt.c, i)); + achievement_count("LIGHTNING", tkills(), tk); + } + +// move the PC in direction d (or stay in place for d == -1) + +bool canmove = true; + +bool checkNeedMove(bool checkonly) { + if(items[itOrbGhost] > 1) return false; + if(cwt.c->wall == waRoundTable) { + if(checkonly) return true; + addMessage(XLAT("It would be impolite to land on the table!")); + } + else if(cwt.c->wall == waLake) { + if(checkonly) return true; + addMessage(XLAT("Ice below you is melting! RUN!")); + } + else if(isFire(cwt.c) && items[itOrbShield] < 2 && !items[itOrbWinter]) { + if(checkonly) return true; + addMessage(XLAT("This spot will be burning soon! RUN!")); + } + else if(items[itOrbGhost] == 1 && !player_passable(cwt.c, NULL, false)) { + if(checkonly) return true; + addMessage(XLAT("Your Aether power has expired! RUN!")); + } + else if(cwt.c->wall == waChasm) { + if(checkonly) return true; + addMessage(XLAT("The floor has collapsed! RUN!")); + } + else return false; + return true; + } + +#define YDIST 101 + +struct yendorinfo { + cell *path[YDIST]; + bool found; + }; + +vector yi; + +int yii = 0; + +bool checkYendor(cell *yendor, bool checkonly) { + int byi = size(yi); + for(int i=0; itype); + + cell *prev = yendor; + + for(int i=0; itype == 7) cwspin(lig, rand() % 2); + + setdist(lig.c, 10, prev); + setdist(lig.c, 9, prev); + } + + nyi.path[YDIST-1] = lig.c; + nyi.found = false; + + cell *key = lig.c; + + for(int b=10; b>=7; b--) setdist(key, b, prev); + + for(int i=-1; itype; i++) { + cell *c2 = i >= 0 ? key->mov[i] : key; + c2->monst = moNone; c2->item = itNone; + if(!passable(c2, NULL, true, true)) { + if(c2->wall == waCavewall) c2->wall = waCavefloor; + else if(c2->wall == waDeadwall) c2->wall = waDeadfloor2; + else if(c2->wall == waLake) c2->wall = waFrozenLake; + else c2->wall = waNone; + } + } + key->item = itKey; + + yi.push_back(nyi); + } + yii = byi; + addMessage(XLAT("You need to find the right Key to unlock this Orb of Yendor!")); + achievement_gain("YENDOR1"); + return false; + } + +int countMyGolems() { + int g=0, dcs = size(dcal); + for(int i=0; imonst == moGolem) g++; + } + return g; + } + +void restoreGolems(int qty) { + int dcs = size(dcal); + for(int i=1; qty && imonst = moGolem, qty--; + } + } + +void activateSafety(eLand l) { + extern void drawSafety(); + int g = countMyGolems(); + drawSafety(); + addMessage(XLAT("You fall into a wormhole!")); + eLand f = firstland; + if(l == laTemple) l = laRlyeh; + if(l == laCamelot) l = laCrossroads; + firstland = l; + for(int i=0; i<65536; i++) euland[i] = laNone; + euland[0] = euland[1] = firstland; + safety = true; + clearMemory(); + initcells(); + initgame(); + firstland = f; + safety = false; + restoreGolems(g); + extern void restartGraph(); + restartGraph(); + } + +bool hasSafeOrb(cell *c) { + return + c->item == itOrbSafety || + c->item == itOrbShield || + c->item == itOrbYendor; + } + + +bool movepcto(int d, bool checkonly = false); + +void checkmove() { + canmove = false; + if(movepcto(-1, true)) canmove = true; + for(int i=0; itype; i++) + if(movepcto(1, true)) canmove = true; + if(!canmove) + achievement_final(true); + if(canmove && timerstopped) { + timerstart = time(NULL); + timerstopped = false; + } + } + +// move the PC. Warning: a very long function! todo: refactor + +void placeGolem(cell *on, cell *moveto, eMonster m) { + if(passable(on, moveto, false, false)) + cwt.c->monst = m; + else if(on->wall == waBonfire) + addMessage(XLAT("%The1 burns!", m)); + } + +void movecost(cell* from, cell *to) { + if(from->land == laPower && to->land != laPower) { + int n=0; + for(int i=0; i= 2 && i != itOrbFire) + items[i] = 2, n++; + if(n) + addMessage(XLAT("As you leave, your powers are drained!")); + } + } + +enum orbAction { roMouse, roKeyboard, roCheck, roMouseForce }; + +// roCheck: return orb type if successful, 0 otherwise +// roMouse/roKeyboard: +// return orb type if successful, eItem(-1) if do nothing, 0 otherwise +eItem targetRangedOrb(cell *c, orbAction a); + +bool haveRangedOrb() { + return + items[itOrbPsi] || items[itOrbDragon] || items[itOrbTeleport] || + items[itOrbIllusion]; + } + +bool isRangedOrb(eItem i) { + return i == itOrbPsi || i == itOrbDragon || i == itOrbTeleport || i == itOrbIllusion; + } + +bool haveRangedTarget() { + if(!haveRangedOrb()) + return false; + for(int i=0; i= 0) { + cwspin(cwt, d); + spinmirrors(d); + d = cwt.spin; + } + if(d != -1 && !checkonly) playermoved = true; + if(!checkonly) invismove = false; + if(d >= 0) { + cell *c2 = cwt.c->mov[d]; + + if(!player_passable(c2, cwt.c, false) && items[itOrbFlash]) { + if(checkonly) return true; + activateFlash(); + checkmove(); + return true; + } + + if(!player_passable(c2, cwt.c, false) && items[itOrbLightning]) { + if(checkonly) return true; + activateLightning(); + checkmove(); + return true; + } + + if(isActiv(c2) && c2->tmp == -1) { + if(checkonly) return true; + addMessage(XLAT("You activate %the1.", c2->wall)); + c2->tmp = 100; + checkmove(); + return true; + } + + if((c2->wall == waThumper/* || (c2->wall == waBigStatue && c2->type == 6)*/) && !monstersnear(c2) && !c2->monst) { + eWall w = c2->wall; + cellwalker push = cwt; + cwstep(push); + cwspin(push, 3); + cwstep(push); +/* if(w == waBigStatue && push.c->type == 7) { + if(checkonly) return false; + addMessage(XLAT("%The1 is too heavy to put it back on the pedestal.", c2->wall)); + return false; + } */ + if((!passable(push.c, c2, false, true) || !passable(push.c, cwt.c, false, true) || push.c->item) && c2->type == 7) { + cwstep(push); + cwspin(push, 1); + cwstep(push); + } + if(!passable(push.c, c2, false, true) || !passable(push.c, cwt.c, false, true) || push.c->item) { + if(checkonly) return false; + addMessage(XLAT("No room to push %the1.", c2->wall)); + return false; + } + if(checkonly) return true; + addMessage(XLAT("You push %the1.", c2->wall)); + push.c->tmp = c2->tmp; + if(c2->land == laAlchemist) + c2->wall = (cwt.c->wall == waFloorB || cwt.c->wall == waFloorA) ? cwt.c->wall : push.c->wall; + else c2->wall = waNone; + push.c->wall = w; + } + +/* if((c2->wall == waBigStatue) && c2->type == 7 && !monstersnear(c2)) { + int q = 0; + for(int i=3; i<=4; i++) { + cellwalker push = cwt; + cwstep(push); + cwspin(push, i); + cwstep(push); + if(passable(push.c, c2, false, true)) q++; + } + if(!q) { + if(checkonly) return false; + addMessage(XLAT("No room to push %the1.", c2->wall)); + return false; + } + if(checkonly) return true; + addMessage(XLAT("You push %the1.", c2->wall)); + c2->wall = waNone; + for(int i=3; i<=4; i++) { + cellwalker push = cwt; + cwstep(push); + cwspin(push, i); + cwstep(push); + if(passable(push.c, c2, false, true)) + push.c->wall = waBigStatue; + } + } */ + + if(c2->wall == waBigStatue && !monstersnear(c2) && !c2->monst) { + if(!canPushStatueOn(cwt.c)) { + if(checkonly) return false; + if(cwt.c->wall == waBonfire) + addMessage(XLAT("You have to escape first!")); + else + addMessage(XLAT("There is not enough space!")); + return false; + } + + if(checkonly) return true; + addMessage(XLAT("You push %the1 behind you!", c2->wall)); + c2->wall = cwt.c->wall; + if(cellUnstable(cwt.c)) + cwt.c->wall = waChasm; + else + cwt.c->wall = waBigStatue; + } + + if(c2->wall == waDryTree && !monstersnear(cwt.c)) { + if(checkonly) return true; + addMessage(XLAT("You start cutting down the tree.")); + c2->wall = waWetTree; + } + else if(c2->wall == waWetTree && !monstersnear(cwt.c)) { + if(checkonly) return true; + addMessage(XLAT("You cut down the tree.")); + c2->wall = waNone; + } + else if(c2->monst == moKnight) { + if(checkonly) return false; + + bool tooeasy = (roundTableRadius(c2) < newRoundTableRadius()); + if(grailWasFound(cwt.c) && rand() % 5 == 0) { + addMessage(XLAT("\"I would like to congratulate you again!\"")); + } + else if(rand() % 5 != 0 && !tooeasy) { + static int i; + i++; + if(i%2) + addMessage(XLAT("\"Find the Holy Grail to become one of us!\"")); + else + addMessage(XLAT("\"The Holy Grail is in the center of the Round Table.\"")); + } + else { + int i = rand() % 3; + if(i == 0) + addMessage(XLAT("\"I enjoy watching the hyperbug battles.\"")); + if(i == 1) + addMessage(XLAT("\"Have you visited a temple in R'Lyeh?\"")); + if(i == 2) + addMessage(XLAT("\"Nice castle, eh?\"")); + } + return false; + } + else if(c2->monst && !isFriendly(c2)) { + if(c2->monst == moWorm || c2->monst == moWormtail || c2->monst == moWormwait) { + if(checkonly) return false; + addMessage(XLAT("You cannot attack Sandworms directly!")); + return false; + } + + if(attackingForbidden(c2, cwt.c)) { + if(checkonly) return false; + addMessage(XLAT("You cannot attack through the Vine!")); + return false; + } + + if(c2->monst == moTentacle || c2->monst == moTentacletail || c2->monst == moTentaclewait) { + if(checkonly) return false; + addMessage(XLAT("You cannot attack Tentacles directly!")); + return false; + } + +/* if(isBug(c2)) { + if(checkonly) return false; + addMessage(XLAT("You cannot win with %the1!", c2->monst)); + return false; + } +*/ + if(c2->monst == moHedge && !items[itOrbThorns]) { + if(checkonly) return false; + addMessage(XLAT("You cannot attack %the1 directly!", c2->monst)); + addMessage(XLAT("Stab them by walking around them.")); + return false; + } + + if(c2->monst == moFlailer) { + if(checkonly) return false; + addMessage(XLAT("You cannot attack %the1 directly!", c2->monst)); + addMessage(XLAT("Make him hit himself by walking away from him.")); + return false; + } + + if(c2->monst == moShadow) { + if(checkonly) return false; + addMessage(XLAT("You cannot defeat the Shadow!")); + return false; + } + + if(c2->monst == moGreater || c2->monst == moGreaterM) { + if(checkonly) return false; + addMessage(XLAT("You cannot defeat the Greater Demon yet!")); + return false; + } + + if(monstersnear(cwt.c, c2)) { + if(checkonly) return false; + addMessage(XLAT("You would be killed by %the1!", which)); + return false; + } + + if(checkNeedMove(checkonly)) + return false; + + if(checkonly) return true; + addMessage(XLAT("You kill %the1.", c2->monst)); + + int mt = c2->monst; + int tk = tkills(); + killMonster(c2); + + int ntk = tkills(); + + if(tk == 0 && ntk > 0) + addMessage(XLAT("That was easy, but groups could be dangerous.")); + + if(tk < 10 && ntk >= 10) + addMessage(XLAT("Good to know that your fighting skills serve you well in this strange world.")); + + if(tk < 50 && ntk >= 50) + addMessage(XLAT("You wonder where all these monsters go, after their death...")); + + if(tk < 100 && ntk >= 100) + addMessage(XLAT("You feel that the souls of slain enemies pull you to the Graveyard...")); + + if(mt == moIvyRoot && ntk>tk) + achievement_gain("IVYSLAYER"); + + gomirrors(0); + } + else if(!player_passable(c2, cwt.c, true)) { + if(checkonly) return false; + if(c2->wall == waFloorA || c2->wall == waFloorB) + addMessage(XLAT("Wrong color!")); + else if(c2->wall == waRoundTable) + addMessage(XLAT("It would be impolite to land on the table!")); + else + addMessage(XLAT("You cannot move through %the1!", c2->wall)); + return false; + } + else if(c2->land == laGameBoard) { + // do not pick up! + if(checkonly) return true; + flipplayer = true; + cwstep(cwt); + setdist(cwt.c, 0, NULL); + bfs(); + checkmove(); + return true; + } + else { + if(c2->item == itOrbYendor && !checkYendor(c2, checkonly)) { + return false; + } + if(c2->item == itHolyGrail) { + if(roundTableRadius(c2) < newRoundTableRadius()) { + if(checkonly) return false; + addMessage(XLAT("That was not a challenge. Find a larger castle!")); + return false; + } + } + if(!hasSafeOrb(c2) && monstersnear(c2)) { + if(checkonly) return false; + + if(items[itOrbFlash]) { + if(checkonly) return true; + activateFlash(); + checkmove(); + return true; + } + + if(items[itOrbLightning]) { + if(checkonly) return true; + activateLightning(); + checkmove(); + return true; + } + + addMessage(XLAT("%The1 would kill you there!", which)); + return false; + } + if(checkonly) return true; + flipplayer = true; + if(c2->item && c2->land == laAlchemist) c2->wall = cwt.c->wall; + if(c2->wall == waRoundTable) { + addMessage(XLAT("You jump over the table!")); + } + + if(cwt.c->wall == waRoundTable) { + int dd = celldistAltRelative(c2) - celldistAltRelative(cwt.c); + + bool tooeasy = (roundTableRadius(c2) < newRoundTableRadius()); + + if(dd>0) { + if(grailWasFound(cwt.c)) { + addMessage(XLAT("The Knights congratulate you on your success!")); + knighted = roundTableRadius(cwt.c); + } + else if(!tooeasy) + addMessage(XLAT("The Knights laugh at your failure!")); + } + else { + if(grailWasFound(cwt.c)) + addMessage(XLAT("The Knights stare at you!")); + else if(tooeasy) + addMessage(XLAT("Come on, this is too easy... find a bigger castle!")); + else + addMessage(XLAT("The Knights wish you luck!")); + } + } + + int pg = gold(); + bool dopickup = true; + + invismove = items[itOrbInvis] > 0; + if(items[itOrbFire]) { + invismove = false; + firetrail(cwt.c); + } + + if(items[itOrbDigging]) { + invismove = false; + earthMove(cwt.c, d); + } + + if(c2->item) { + invismove = false; + string s0 = ""; + if(0) ; + if(gold() == 0) + addMessage(XLAT("Wow! %1! This trip should be worth it!", c2->item)); + else if(gold() == 1) + addMessage(XLAT("For now, collect as much treasure as possible...")); + else if(gold() == 2) + addMessage(XLAT("Prove yourself here, then find new lands, with new quests...")); + else if(!items[c2->item] && itemclass(c2->item) == IC_TREASURE) + addMessage(XLAT("You collect your first %1!", c2->item)); + else if(c2->item == itKey) + addMessage(XLAT("You have found the Key! Now unlock this Orb of Yendor!")); + else if(c2->item == itGreenStone && !items[itGreenStone]) + addMessage(XLAT("This orb is dead...")); + else if(c2->item == itGreenStone) + addMessage(XLAT("Another Dead Orb.")); + else if(itemclass(c2->item) != IC_TREASURE) + addMessage(XLAT("You have found %the1!", c2->item)); + else if(items[c2->item] == 4 && maxgold() == 4) { + addMessage(XLAT("You feel that %the2 become%s2 more dangerous.", c2->item, c2->land)); + addMessage(XLAT("With each %1 you collect...", c2->item, c2->land)); + } + else if(items[c2->item] == 9 && maxgold() == 9) + addMessage(XLAT("Are there any magical orbs in %the1?...", c2->land)); + else if(items[c2->item] == 10 && maxgold() == 10) { + addMessage(XLAT("You feel that %the1 slowly become%s1 dangerous...", c2->land)); + addMessage(XLAT("Better find some other place.")); + } + else if(c2->item == itSpice && items[itSpice] == 7) + addMessage(XLAT("You have a vision of the future, fighting demons in Hell...")); + else if(c2->item == itElixir && items[itElixir] == 4) + addMessage(XLAT("With this Elixir, your life should be long and prosperous...")); + else if(c2->item == itBone && items[itBone] == 6) + addMessage(XLAT("The Necromancer's Totem contains hellish incantations...")); + else if(c2->item == itStatue && items[itStatue] == 6) + addMessage(XLAT("The inscriptions on the Statue of Cthulhu point you toward your destiny...")); + else if(c2->item == itStatue && items[itStatue] == 4) + addMessage(XLAT("There must be some temples of Cthulhu in R'Lyeh...")); + else if(c2->item == itDiamond && items[itDiamond] == 8) + addMessage(XLAT("Still, even greater treasures lie ahead...")); + else if(c2->item == itFernFlower && items[itFernFlower] == 4) + addMessage(XLAT("You overheard Hedgehog Warriors talking about emeralds...")); + else if(c2->item == itEmerald && items[itEmerald] == 4) + addMessage(XLAT("You overhear miners talking about a castle...")); + else if(c2->item == itEmerald && items[itEmerald] == 5) + addMessage(XLAT("A castle in the Crossroads...")); + else { + string t = XLAT("You collect %the1.", c2->item); + addMessage(t); + } + } + + if(c2->item == itOrbSpeed) { + items[c2->item] += 31; + if(items[c2->item] > 67) items[c2->item] = 67; + } + else if(c2->item == itOrbLife) { + placeGolem(cwt.c, c2, moGolem); + } + else if(c2->item == itOrbSafety) { + items[c2->item] += 7; + activateSafety(c2->land); + return true; + } + else if(c2->item == itOrbLightning) { + items[c2->item] += 78; + if(items[c2->item] > 777) items[c2->item] = 777; + } + else if(c2->item == itOrbThorns) { + items[c2->item] += 78; + if(items[c2->item] > 151) items[c2->item] = 151; + } + else if(c2->item == itOrbFlash) { + items[c2->item] += 78; + if(items[c2->item] > 777) items[c2->item] = 777; + } + else if(c2->item == itOrbShield) { + items[c2->item] += 16; + if(items[c2->item] > 77) items[c2->item] = 77; + } + else if(c2->item == itOrbWinter) { + items[c2->item] += 31; + if(items[c2->item] > 77) items[c2->item] = 77; + } + else if(c2->item == itOrbFire) { + items[c2->item] += 31; + if(items[c2->item] > 77) items[c2->item] = 77; + } + else if(c2->item == itOrbDragon) { + items[c2->item] += 78; + if(items[c2->item] > 111) items[c2->item] = 111; + } + else if(c2->item == itOrbIllusion) { + items[c2->item] += 78; + if(items[c2->item] > 111) items[c2->item] = 111; + } + else if(c2->item == itOrbPsi) { + items[c2->item] += 78; + if(items[c2->item] > 111) items[c2->item] = 111; + } + else if(c2->item == itOrbInvis) { + items[c2->item] += 31; + if(items[c2->item] > 77) items[c2->item] = 77; + } + else if(c2->item == itOrbGhost) { + items[c2->item] += 31; + if(items[c2->item] > 77) items[c2->item] = 77; + } + else if(c2->item == itOrbDigging) { + items[c2->item] += 78; + if(items[c2->item] > 101) items[c2->item] = 101; + } + else if(c2->item == itOrbTeleport) { + items[c2->item] += 78; + if(items[c2->item] > 201) items[c2->item] = 201; + } + else if(c2->item == itOrbYendor) { + for(int i=0; i<4; i++) switch(rand() % 12) { + case 0: items[itOrbSpeed] += 31; break; + case 1: items[itOrbLightning] += 78; break; + case 2: items[itOrbFlash] += 78; break; + case 3: items[itOrbShield] += 31; break; + case 4: items[itOrbWinter] += 151; break; + case 5: items[itOrbDigging] += 151; break; + case 6: items[itOrbTeleport] += 151; break; + case 7: items[itOrbThorns] += 151; break; + case 8: items[itOrbInvis] += 151; break; + case 9: items[itOrbPsi] += 151; break; + case 10: items[itOrbGhost] += 151; break; + case 11: items[itOrbFire] += 151; break; + } + items[itOrbYendor]++; + items[itKey]--; + addMessage(XLAT("CONGRATULATIONS!")); + achievement_collection(itOrbYendor, pg, gold()); + achievement_victory(false); + } + else if(c2->item == itHolyGrail) { + int v = newRoundTableRadius() + 12; + items[itOrbTeleport] += v; + items[itOrbSpeed] += v; + items[itHolyGrail]++; + addMessage(XLAT("Congratulations! You have found the Holy Grail!")); + if(!euclid) c2->master->alt->fjordval |= GRAIL_FOUND; + achievement_collection(c2->item, pg, gold()); + } + else if(c2->item == itKey) { + for(int i=0; iitem == itGrimoire && items[itGrimoire] > celldistAlt(c2)/-TEMPLE_EACH) { + addMessage(XLAT("You already have this Grimoire! Seek new tomes in the inner circles.")); + dopickup = false; + } + else { + bool lhu = hellUnlocked(); + if(c2->item) items[c2->item]++; + int g2 = gold(); + + if(c2->item == itHyperstone && items[itHyperstone] == 10) + achievement_victory(true); + + achievement_collection(c2->item, pg, g2); + + if(pg < 15 && g2 >= 15) + addMessage(XLAT("Collect treasure to access more different lands...")); + if(pg < 30 && g2 >= 30) + addMessage(XLAT("You feel that you have enough treasure to access new lands!")); + if(pg < 45 && g2 >= 45) + addMessage(XLAT("Collect more treasures, there are still more lands waiting...")); + if(pg < 60 && g2 >= 60) + addMessage(XLAT("You feel that the stars are right, and you can access R'Lyeh!")); + if(pg < 75 && g2 >= 75) + addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell...")); + if(pg < 90 && g2 >= 90) + addMessage(XLAT("To access Hell, collect 10 treasures each of 9 kinds...")); + if(hellUnlocked() && !lhu) { + addMessage(XLAT("Abandon all hope, the gates of Hell are opened!")); + addMessage(XLAT("And the Orbs of Yendor await!")); + } + } + + if(dopickup) c2->item = itNone; +// if(c2->land == laHive) +// c2->heat = 1; + + int numOrb = 0; + for(int i=0; iwall == waNone) + cwt.c->wall = waIcewall; + } + + movecost(cwt.c, c2); + + if(c2->monst == moGolem || c2->monst == moIllusion) { + addMessage(XLAT("You switch places with %the1.", c2->monst)); + placeGolem(cwt.c, c2, c2->monst); + c2->monst = moNone; + } + else if(c2->monst) { + addMessage(XLAT("You rejoin %the1.", c2->monst)); + killMonster(c2); + } + + stabbingAttack(cwt.c, c2); + cwstep(cwt); + + gomirrors(1); + + if(c2->wall == waMirror) { + invismove = false; + addMessage(XLAT("The mirror shatters!")); + if(c2->land == laMirror) { + int g = gold(); + items[itShard]++; + achievement_collection(itShard, g+1, g); + } + c2->wall = waNone; + createMirrors(cwt.c, cwt.spin, moMirage); + } + + if(c2->wall == waGlass && items[itOrbGhost] > 2) { + addMessage(XLAT("Your Aether powers are drained by %the1!", c2->wall)); + items[itOrbGhost] = 2; + } + + if(c2->wall == waCloud) { + invismove = false; + addMessage(XLAT("The cloud turns into a bunch of images!")); + if(c2->land == laMirror) { + int g = gold(); + items[itShard]++; + achievement_collection(itShard, g+1, g); + } + c2->wall = waNone; + createMirages(cwt.c, cwt.spin, moMirage); + } + + if(cellUnstable(c2) && !items[itOrbGhost]) + c2->wall = waChasm; + + countLocalTreasure(); + landvisited[cwt.c->land] = true; + setdist(cwt.c, 0, NULL); + } + } + else { + if(checkNeedMove(checkonly)) + return false; + if(monstersnear(cwt.c)) { + if(checkonly) return false; + addMessage(XLAT("%The1 would get you!", which)); + return false; + } + if(checkonly) return true; + if(d == -2 && items[itGreenStone] && cwt.c->item == itNone) { + items[itGreenStone]--; + if(false) { + cwt.c->item = itNone; + spill(cwt.c, eWall(cwt.c->wall ^ waFloorA ^ waFloorB), 3); + addMessage(XLAT("The slime reacts with %the1!", itGreenStone)); + } + else { + cwt.c->item = itGreenStone; + addMessage(XLAT("You drop %the1.", itGreenStone)); + } + } + else if(d == -2) { + if(gold() >= 300) + addMessage(XLAT("You feel great, like a true treasure hunter.")); + else if(gold() >= 200) + addMessage(XLAT("Your eyes shine like gems.")); + else if(gold() >= 100) + addMessage(XLAT("Your eyes shine as you glance at your precious treasures.")); + else if(gold() >= 50) + addMessage(XLAT("You glance at your great treasures.")); + else if(gold() >= 10) + addMessage(XLAT("You glance at your precious treasures.")); + else if(gold() > 0) + addMessage(XLAT("You glance at your precious treasure.")); + else + addMessage(XLAT("Your inventory is empty.")); + } + } + DEBT("bfs"); + bfs(); + destroyStrayMirrors(); + DEBT("heat"); + heat(); + DEBT("rop"); + int phase1 = (1 & items[itOrbSpeed]); + reduceOrbPowers(); + DEBT("mmo"); + int phase2 = (1 & items[itOrbSpeed]); + if(!phase2) movemonsters(); + if(cwt.c->land == laPower && !phase1) { bfs(); moveFastMonsters(); } + DEBT("lc"); + if(!phase1) livecaves(); + if(!phase1) dryforest(); + DEBT("check"); + checkmove(); + DEBT("done"); + return true; + } + +/* bool isPsiTarget(cell *dst) { + return + dst->cpdist > 1 && + dst->monst && + !(isWorm(dst) || dst->monst == moShadow); + } */ + +void teleportTo(cell *dest) { + cwt.c->monst = dest->monst; + dest->monst = moNone; + movecost(cwt.c, dest); + cwt.c = dest; cwt.spin = rand() % dest->type; flipplayer = !!(rand() % 2); + items[itOrbTeleport] = 0; + + addMessage(XLAT("You teleport to a new location!")); + destroyMirrors(); + + for(int i=9; i>=0; i--) + setdist(cwt.c, i, NULL); + + bfs(); + checkmove(); + } + +void psi_attack(cell *dest) { + addMessage(XLAT("You kill %the1 with a mental blast!", dest->monst)); + killMonster(dest); + items[itOrbPsi] -= 30; + if(items[itOrbPsi]<0) items[itOrbPsi] = 0; + checkmove(); + } + +bool flammable(cell *c) { + return + c->wall == waNone || c->wall == waFloorA || c->wall == waFloorB || + c->wall == waCavefloor || c->wall == waDeadfloor || + c->wall == waDryTree || c->wall == waWetTree || + c->wall == waVinePlant || c->wall == waVineHalfA || c->wall == waVineHalfB || + c->wall == waIcewall; + } + +void placeDragonfire(cell *c) { + if(cellUnstable(c)) + c->wall = waChasm; + else if(c->wall == waNone && c->land == laCocytus) + c->wall = waLake, c->heat += 20; + else if(cellHalfvine(c)) + flameHalfvine(c, 20); + else { + c->wall = waBonfire; + c->tmp = 20; + } + if(itemBurns(c->item)) + addMessage(XLAT("%The1 burns!", c->item)), c->item = itNone; + addMessage(XLAT("You throw fire!")); + items[itOrbDragon] -= 5; + if(items[itOrbDragon]<0) items[itOrbDragon] = 0; + checkmove(); + } + +void placeIllusion(cell *c) { + c->monst = moIllusion; + items[itOrbIllusion] -= 5; + if(items[itOrbIllusion]<0) items[itOrbIllusion] = 0; + addMessage(XLAT("You create an Illusion!")); + checkmove(); + } + +eItem targetRangedOrb(cell *c, orbAction a) { + if(!haveRangedOrb()) return itNone; + if(c == cwt.c || isNeighbor(cwt.c, c)) { + if(a == roKeyboard || a == roMouseForce ) + addMessage(XLAT("You cannot target that close!")); + return itNone; + } + if(c->cpdist > 7) { + if(a != roCheck) + addMessage(XLAT("You cannot target that far away!")); + return itNone; + } + + // (1) switch with an illusion + if(items[itOrbTeleport] && c->monst == moIllusion) { + if(a != roCheck) teleportTo(c); + return itOrbTeleport; + } + + // (2) place illusion + if(items[itOrbIllusion] && c->monst == moNone && c->item == itNone && passable(c, NULL, false, true)) { + if(a != roCheck) placeIllusion(c); + return itOrbIllusion; + } + + // (3) teleport + if(items[itOrbTeleport] && c->monst == moNone && c->item == itNone && passable(c, NULL, false, true)) { + if(a != roCheck) teleportTo(c); + return itOrbTeleport; + } + + // (4) remove an illusion + if(items[itOrbIllusion] && c->monst == moIllusion) { + if(a != roCheck) { + addMessage(XLAT("You take the Illusion away.")); + items[itOrbIllusion] += 4; + c->monst = moNone; + } + return itOrbIllusion; + } + + // (5) psi blast + if(items[itOrbPsi] && c->monst && !isWorm(c) && c->monst != moShadow) { + if(a != roCheck) psi_attack(c); + return itOrbPsi; + } + + // (6) place fire + if(items[itOrbDragon] && flammable(c)) { + if(a != roCheck) placeDragonfire(c); + return itOrbDragon; + } + + if(a == roCheck) return itNone; + + if(items[itOrbPsi] && c->monst) { + addMessage(XLAT("%The1 is immune to mental blasts!", c->monst)); + } + else if(items[itOrbTeleport] && c->monst) { + addMessage(XLAT("Cannot teleport on a monster!")); + } + else if(items[itOrbIllusion] && c->item) + addMessage(XLAT("Cannot cast illusion on an item!")); + else if(items[itOrbIllusion] && c->monst) + addMessage(XLAT("Cannot cast illusion on a monster!")); + else if(items[itOrbIllusion] && !passable(c, NULL, false, true)) + addMessage(XLAT("Cannot cast illusion here!")); + else if(items[itOrbTeleport] && c->item) { + addMessage(XLAT("Cannot teleport on an item!")); + } + else if(items[itOrbTeleport] && !passable(c, NULL, false, true)) { + addMessage(XLAT("Cannot teleport here!")); + } + else if(items[itOrbDragon] && !flammable(c)) { + addMessage(XLAT("Cannot throw fire there!")); + } + else return eItem(0); + + return eItem(-1); + } + +#define MAXBOX 120 +#define POSSCORE 107 // update this when new boxes are added! + +struct score { + string ver; + int box[MAXBOX]; + }; + +int savebox[MAXBOX], boxid; +bool saving; + +string boxname[MAXBOX]; +bool fakebox[MAXBOX]; + +void applyBox(int& t) { + if(saving) savebox[boxid++] = t; + else t = savebox[boxid++]; + } + +void applyBoxNum(int& i, string name = "") { + fakebox[boxid] = (name == ""); + boxname[boxid] = name; + applyBox(i); + } + +// just skips the value when loading +void applyBoxSave(int i, string name = "") { + fakebox[boxid] = (name == ""); + boxname[boxid] = name; + applyBox(i); + } + +int applyBoxLoad(string name = "") { + fakebox[boxid] = (name == ""); + boxname[boxid] = name; + int i=0; applyBox(i); + return i; + } + +void applyBoxI(eItem it, bool f = false) { + boxname[boxid] = iinf[it].name; + fakebox[boxid] = f; + applyBox(items[it]); + } + +void applyBoxM(eMonster m, bool f = false) { + fakebox[boxid] = f; + boxname[boxid] = minf[m].name; + applyBox(kills[m]); + } + +void killbox(eMonster m, int& val) { + if(saving) kills[m] = val; + else { val = kills[m]; kills[m] = 0; } + } + +void applyBoxes() { + + applyBoxSave(timerstart, "time elapsed"); + time_t timer = time(NULL); + applyBoxSave(timer, "date"); + applyBoxSave(gold(), "treasure collected"); + applyBoxSave(tkills(), "total kills"); + applyBoxNum(turncount, "turn count"); + applyBoxNum(cellcount, "cells generated"); + + if(!saving) timerstart = time(NULL); + + for(int i=0; iland); + else firstland = eLand(applyBoxLoad()); + + for(int i=itOrbLightning; i<25; i++) applyBoxI(eItem(i), true); + + applyBoxI(itRoyalJelly); + applyBoxI(itWine); + applyBoxI(itSilver); + applyBoxI(itEmerald); + applyBoxI(itPower); + applyBoxI(itOrbFire, true); + applyBoxI(itOrbInvis, true); + applyBoxI(itOrbGhost, true); + applyBoxI(itOrbPsi, true); + applyBoxM(moBug0); + applyBoxM(moBug1); + applyBoxM(moBug2); + applyBoxM(moVineBeast); + applyBoxM(moVineSpirit); + applyBoxM(moLancer); + applyBoxM(moFlailer); + applyBoxM(moEarthElemental); + applyBoxM(moDarkTroll); + applyBoxM(moWitch); + applyBoxM(moWitchFire); + applyBoxM(moWitchFlash); + applyBoxM(moWitchGhost); + applyBoxM(moWitchSpeed); + applyBoxM(moEvilGolem); + applyBoxM(moWitchWinter); + applyBoxI(itHolyGrail); + applyBoxI(itGrimoire); + applyBoxM(moKnight); + applyBoxM(moCultistLeader); + } + +void saveBox() { + boxid = 0; saving = true; applyBoxes(); + } + +void loadBox() { + // have boxid + boxid = 0; saving = false; applyBoxes(); + } + +// certify that saves and achievements were received +// in an official version of HyperRogue +#ifdef CERTIFY +#include "certify.cpp" +#else +bool tampered; + +void saveCertificate(FILE *f) {} +bool loadCertificate(FILE *f, score& sc) {return true; } + +int achievement_certify(const char *s, int a, int b, int c) { return 0; } + +#endif + +void saveStats() { + if(euclid) return; +#ifndef ANDROID + + FILE *f = fopen(scorefile, "at"); + if(!f) { + printf("Could not open the score file '%s'!\n", scorefile); + addMessage(XLAT("Could not open the score file: ", scorefile)); + return; + } + + if(showoff) return; + + time_t timer; + timer = time(NULL); + char sbuf[128]; strftime(sbuf, 128, "%c", localtime(&timerstart)); + char buf[128]; strftime(buf, 128, "%c", localtime(&timer)); + + fprintf(f, "HyperRogue: game statistics (version "VER")\n"); + if(cheater) + fprintf(f, "CHEATER! (cheated %d times)\n", cheater); + if(true) { + + fprintf(f, VER); + saveBox(); + + for(int i=0; i\n", kills[i], minf[i].name, i); + + fprintf(f, "\n\n\n"); + + printf("Game statistics saved to %s\n", scorefile); + addMessage(XLAT("Game statistics saved to %1", scorefile)); + fclose(f); +#endif + } + +bool havesave = true; + +#ifndef ANDROID +// load the save +void loadsave() { + + printf("Trying to load a save.\n"); + FILE *f = fopen(scorefile, "rt"); + havesave = f; + if(!f) return; + score sc; + bool ok = false; + bool tamper = false; + while(!feof(f)) { + char buf[120]; + if(fgets(buf, 120, f) == NULL) break; + if(buf[0] == 'H' && buf[1] == 'y') { + if(fscanf(f, "%s", buf) <= 0) break; sc.ver = buf; + if(sc.ver < "4.4" || sc.ver == "CHEATER!") continue; + ok = true; + for(int i=0; iitem]++; + c->item = itNone; + } + if(u == ' ') + c->item = itNone; + + extern void movepckeydir(int); + if(sym == 'd' || sym == SDLK_KP6) movepckeydir(0); + if( sym == SDLK_KP3) movepckeydir(1); + if(sym == 'x' || sym == SDLK_KP2) movepckeydir(2); + if( sym == SDLK_KP1) movepckeydir(3); + if(sym == 'a' || sym == SDLK_KP4) movepckeydir(4); + if( sym == SDLK_KP7) movepckeydir(5); + if(sym == 'w' || sym == SDLK_KP8) movepckeydir(6); + if( sym == SDLK_KP9) movepckeydir(7); + + if(u == 'g') + c->item = itGreenStone; + if(u == 'r') + c->item = itOrbSpeed; + if(u == 't') + c->item = itOrbFlash; + if(u == 'o') + c->item = itOrbShield; + if(u == 'i') + c->item = itOrbTeleport; + if(u == 'p') + c->item = itOrbLightning; + if(u == 'h') + c->item = itDiamond; + if(u == 'j') + c->item = itHell; + if(u == 'k') + c->item = itFernFlower; + if(u == 'l') + c->item = itSapphire; + + if(boardmode == 'f') { + int fv = fjordval(c); + if(u == '0' || u == '1' || u == '2' || u == '3' || u == '4') fjordwalled[fv] = !fjordwalled[fv]; + if(u == '1' || u == '4') fjordwalled[fv^1] = !fjordwalled[fv^1]; + if(u == '2' || u == '4') fjordwalled[fv^2] = !fjordwalled[fv^2]; + if(u == '3' || u == '4') fjordwalled[fv^3] = !fjordwalled[fv^3]; + return; + } + + if(u == '0') + c->wall = waNone; + if(u == '1') + c->wall = waFloorA; + if(u == '2') + c->wall = waFloorB; + if(u == '3') + c->wall = waFrozenLake; + if(u == '4') + c->wall = waCavefloor; + if(u == '5') + c->wall = waLake; + if(u == '6') + c->wall = waCavewall; + if(u == '7') + c->wall = waIcewall; + if(u == '8') + c->wall = waDryTree; + if(u == '9') + c->wall = waColumn; + } +#endif + +static int orbid = 0; + +eItem nextOrb() { + orbid++; + eItem i = eItem(orbid % ittypes); + if(itemclass(i) == IC_ORB) return i; + else return nextOrb(); + } + +eItem randomTreasure() { + eItem i = eItem(rand() % ittypes); + if(itemclass(i) == IC_TREASURE) return i; + else return randomTreasure(); + } + +eItem randomTreasure2(int cv) { + int bq = 60000, cq = 0; + eItem best = itDiamond; + eItem lt = localTreasureType(); + for(int a=1; aland == laCrossroads) q -= 5; + if(q < bq) bq = q, cq = 0; + if(q == bq) { cq++; if(rand() % cq == 0) best = i; } + } + return best; + } + +extern int webdisplay; + +void applyCheat(char u, cell *c = NULL) { + if(u == 'M' && cwt.c->type == 6) { + addMessage(XLAT("You summon some Mirages!")); + cheater++; + createMirrors(cwt.c, cwt.spin, moMirage), + createMirages(cwt.c, cwt.spin, moMirage); + } + if(u == 'G') { + addMessage(XLAT("You summon a golem!")); + cheater++; + int i = cwt.spin; + if(passable(cwt.c->mov[i], NULL, false, false)) + cwt.c->mov[i]->monst = moGolem; + } + if(u == 'L') { + do { + firstland = eLand(firstland+1); + if(firstland == landtypes) firstland = eLand(2); + } + while(firstland == laGameBoard || firstland == laCamelot || firstland == laTemple); + euclidland = firstland; + cheater++; addMessage(XLAT("You will now start your games in %1", firstland)); + } + if(u == 'C') { + cheater++; + activateSafety(laCrossroads); + addMessage(XLAT("Activated the Hyperstone Quest!")); + for(int i=0; itype; i++) + if(passable(cwt.c->mov[i], NULL, false, false)) { + eItem it = nextOrb(); + cwt.c->mov[i]->item = it; + } + } + if(u == 'F') { + items[itOrbFlash] += 1; + items[itOrbTeleport] += 1; + items[itOrbLightning] += 1; + items[itOrbSpeed] += 1; + items[itOrbShield] += 1; + cheater++; addMessage(XLAT("Orb power gained!")); + } + if(u == 'D') { + items[itGreenStone] += 10; + cheater++; addMessage(XLAT("Dead orbs gained!")); + } + if(u == 'Y') { + items[itOrbYendor] ++; + cheater++; addMessage(XLAT("Orb of Yendor gained!")); + } + if(u == 'T') { + items[randomTreasure2(10)] += 10; + cheater++; addMessage(XLAT("Treasure gained!")); + } + if(u == 'T'-64) { + items[randomTreasure2(100)] += 100; + cheater++; addMessage(XLAT("Lots of treasure gained!")); + } + if(u == 'W') { + addMessage(XLAT("You summon a sandworm!")); + cheater++; + int i = cwt.spin; + if(passable(cwt.c->mov[i], NULL, false, false)) + cwt.c->mov[i]->monst = moWorm, + cwt.c->mov[i]->mondir = NODIR; + } + if(u == 'I') { + addMessage(XLAT("You summon an Ivy!")); + cheater++; + int i = cwt.spin; + int j = cwt.c->spn[i]; + cell* c = cwt.c->mov[i]->mov[(j+3)%cwt.c->mov[i]->type]; + if(passable(c, NULL, false, false)) buildIvy(c, 0, 1); + } + if(u == 'E') { + addMessage(XLAT("You summon a monster!")); + cheater++; + int i = cwt.spin; + if(cwt.c->mov[i]->wall == waChasm) + cwt.c->mov[i]->wall = waNone; + if(passable(cwt.c->mov[i], NULL, true, false)) { + eMonster mo[7] = { moEagle, moPyroCultist, moGhost, moTroll, moKnight, moMiner, moVineBeast }; + cwt.c->mov[i]->monst = mo[rand() % 7]; + } + } + if(u == 'H') { + addMessage(XLAT("You summon some Thumpers!")); + cheater++; + for(int i=0; itype; i++) + if(passable(cwt.c->mov[i], NULL, false, false)) + cwt.c->mov[i]->wall = rand() % 2 ? waThumper : waBigStatue, cwt.c->mov[i]->tmp = -1; + } + if(u == 'B') { + addMessage(XLAT("You summon a bonfire!")); + cheater++; + int i = cwt.spin; + if(passable(cwt.c->mov[i], NULL, false, false)) + cwt.c->mov[i]->wall = waBonfire, cwt.c->mov[i]->tmp = -1; + } + if(u == 'Z') { + cwt.spin++; flipplayer = false; + cwt.spin %= cwt.c->type; + } + if(u == 'J') { + if(items[localTreasureType()] > 0) + items[localTreasureType()] = 0; + else for(int i=1; iland); + items[itOrbSafety] += 3; + cheater++; addMessage(XLAT("Activated Orb of Safety!")); + } + if(u == 'U') { + activateSafety(firstland); + cheater++; addMessage(XLAT("Teleported to %1!", firstland)); + } + if(u == 'W'-64) { + webdisplay++; + cheater++; addMessage(XLAT("Cheat-changed the display.", firstland)); + } + } + +void generateAlts(heptagon *h) { + if(!h->alt) return; + h->c7->bardir = NOBARRIERS; + for(int i=0; i<7; i++) if(h->c7->mov[i]) + h->c7->mov[i]->bardir = NOBARRIERS; + for(int i=0; i<7; i++) + createStep(h->alt, i)->alt = h->alt->alt; + int relspin = -4; // for horocycles it must go the other way + for(int i=0; i<7; i++) for(int j=0; j<7; j++) { + createStep(h, i); + if(h->move[i]->alt == h->alt->move[j]) + relspin = (i-j+7) % 7; + } + if(relspin == -4) { + if(h->alt != h->alt->alt) { + printf("relspin {%p:%p}\n", h->alt, h->alt->alt); + for(int i=0; i<7; i++) printf("%p ", h->alt->move[i]); printf(" ALT\n"); + for(int i=0; i<7; i++) printf("%p ", h->move[i]); printf(" REAL\n"); + for(int i=0; i<7; i++) printf("%p ", h->move[i]->alt); printf(" REAL ALT\n"); + } + relspin = 3; + } + // h[relspin] matches alt[0] +//printf("{%d~%d}\n", h->distance, h->alt->distance); + for(int i=0; i<7; i++) { + int ir = (7+i-relspin)%7; + heptagon *hm = h->alt->move[ir]; + heptagon *ho = createStep(h, i); +// printf("[%p:%d ~ %p:%d] %p ~ %p\n", +// h, i, h->alt, ir, +// ho, hm); + if(ho->alt && ho->alt != hm) { + if(ho->alt->alt == hm->alt) { + printf("ERROR: alt cross! [%d -> %d]\n", ho->alt->distance, hm->distance); + // exit(1); + } + continue; + } + ho->alt = hm; + } + } + +heptagon *createAlternateMap(cell *c, int rad, hstate firststate) { + + // check for direction + int gdir = -1; + for(int i=0; itype; i++) { + if(c->mov[i] && c->mov[i]->mpdist < c->mpdist) gdir = i; + } + if(!gdir) return NULL; + + // check for non-crossing + int bd = 2; + cellwalker bb(c, bd); + cellwalker bb2 = bb; + if(!(checkBarriersFront(bb) && checkBarriersBack(bb2))) { + return NULL; + } + + // okay, let's go then! + cellwalker bf(c, gdir); + cell *cx[rad+1]; + for(int i=0; itype == 6) + cwspin(bf, 3); + else + cwspin(bf, 3 + rand() % 2); + cwstep(bf); + } + cx[rad] = bf.c; + heptagon *h = bf.c->master; + + heptagon *alt = new heptagon; + allAlts.push_back(alt); +//printf("new alt {%p}\n", alt); + alt->s = firststate; + alt->fjordval = 0; + for(int i=0; i<7; i++) alt->move[i] = NULL; + alt->distance = 0; + alt->c7 = NULL; + alt->alt = alt; + h->alt = alt; + + for(int d=rad; d>=0; d--) { + generateAlts(cx[d]->master); + cx[d]->bardir = NOBARRIERS; + } + + return alt; +//for(int d=rad; d>=0; d--) printf("%3d. %p {%d}\n", d, cx[d]->master, cx[d]->master->alt->distance); + } diff --git a/geometry.cpp b/geometry.cpp new file mode 100644 index 00000000..c81a2abb --- /dev/null +++ b/geometry.cpp @@ -0,0 +1,124 @@ +// Hyperbolic Rogue +// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details + +// geometrical constants + +ld tessf, crossf, hexf; + +#define ALPHA (M_PI*2/7) + +hyperpoint Crad[42]; + +transmatrix heptmove[7], hexmove[7]; + +void precalc() { + + ld fmin = 1, fmax = 2; + + for(int p=0; p<100; p++) { + ld f = (fmin+fmax) / 2; + hyperpoint H = xpush(f) * C0; + ld v1 = intval(H, C0), v2 = intval(H, spin(2*M_PI/7)*H); + if(v1 > v2) fmin = f; else fmax = f; + } + tessf = fmin; + + fmin = 0, fmax = 2; + for(int p=0; p<100; p++) { + ld f = (fmin+fmax) / 2; + hyperpoint H = spin(M_PI/7) * xpush(f) * C0; + ld v1 = intval(H, C0), v2 = intval(H, xpush(tessf) * C0); + if(v1 < v2) fmin = f; else fmax = f; + } + crossf = fmin; + + fmin = 0, fmax = tessf; + for(int p=0; p<100; p++) { + ld f = (fmin+fmax) / 2; + hyperpoint H = xpush(f) * C0; + hyperpoint H1 = spin(2*M_PI/7) * H; + hyperpoint H2 = xpush(tessf-f) * C0; + ld v1 = intval(H, H1), v2 = intval(H, H2); + if(v1 < v2) fmin = f; else fmax = f; + } + hexf = fmin; + + for(int i=0; i<42; i++) + Crad[i] = spin(2*M_PI*i/42) * xpush(.4) * C0; + for(int d=0; d<7; d++) + heptmove[d] = spin(-d * ALPHA) * xpush(tessf) * spin(M_PI); + for(int d=0; d<7; d++) + hexmove[d] = spin(-d * ALPHA) * xpush(-crossf)* spin(M_PI); + + } + +transmatrix ddi(ld dir, ld dist) { + // EUCLIDEAN + if(euclid) + return eupush(cos(M_PI*dir/42) * dist, -sin(M_PI*dir/42) * dist); + else + return spin(M_PI*dir/42) * xpush(dist) * spin(-M_PI*dir/42); + } + +// tesselation drawing + +#define NUMFACE 500 +transmatrix tess[NUMFACE]; + +void genTesselation() { + int N = 1; + tess[0] = Id; + for(int i=0; i %d\n", i,t, N); + tess[N] = T; N++; + if(N == NUMFACE) return; + nextt: ; + } + } + } + +struct ltd { + hyperpoint P1; + hyperpoint P2; + int col; + }; + +vector lines; + +void addline(hyperpoint P1, hyperpoint P2, int col) { + ltd L; + L.P1 = P1; L.P2 = P2; L.col = col; + lines.push_back(L); + } + +void addlines() { + + // change the if(0) conditions to see the underlying structure + + if(0) for(int t =0; t + +#ifdef AUDIO +#include +#endif +bool audio; +int audiovolume = 60; + +#ifndef MAC +#undef main +#endif + +#include + +#ifdef GFX +#include +#endif +#endif + +#ifndef MOBILE +#ifdef GL +#ifdef MAC +#include +#include +#else +#include +#include +#endif + +#ifdef MAC +#include +#else +#include +#endif +#endif +#endif + +#ifdef ANDROID +#ifndef FAKE +#ifdef GL +#include +#include +#include +#endif +#endif +#endif + + +#ifndef MOBILE + +// x resolutions + +#define NUMMODES 7 + +SDL_Surface *s; +TTF_Font *font[256]; +SDL_Joystick *stick, *panstick; + +#endif + +int webdisplay = 0; + +// R:239, G:208, B:207 + +struct videopar { + ld scale, eye, alpha, aspeed; + bool full; + bool goteyes; + bool quick; + bool darkhepta; + bool shifttarget; + + int xres, yres, framelimit; + + int xscr, yscr; + + // paramaters calculated from the above + int xcenter, ycenter; + int radius; + ld alphax, beta; + + int fsize; + int flashtime; + + int wallmode, monmode, axes; + + // for OpenGL + float scrdist; + + bool usingGL; + bool usingAA; + + int joyvalue, joyvalue2, joypanthreshold; + float joypanspeed; + + bool female; + int language; + int boardmode; + + int skincolor, haircolor, dresscolor, swordcolor; + int killreduction; + }; + +int skincolors[] = { 7, 0xD0D0D0FF, 0xEFD0C9FF, 0xC77A58FF, 0xA58869FF, 0x602010FF, 0xFFDCB1FF, 0xEDE4C8FF }; +int haircolors[] = { 8, 0x686868FF, 0x8C684AFF, 0xF2E1AEFF, 0xB55239FF, 0xFFFFFFFF, 0x804000FF, 0x502810FF, 0x301800FF }; +int dresscolors[] = { 6, 0xC00000FF, 0x00C000FF, 0x0000C0FF, 0xC0C000FF, 0xC0C0C0FF, 0x202020FF }; +int swordcolors[] = { 6, 0xC0C0C0FF, 0xFFFFFFFF, 0xFFC0C0FF, 0xC0C0FFFF, 0x808080FF, 0x202020FF }; + +// is the player using mouse? (used for auto-cross) +bool mousing = true; + +// is the mouse button pressed? +bool mousepressed = false; + +// +int axestate; + +int ticks; + +hyperpoint ccenter; ld crad; + +videopar vid; +int default_language; + +int playergender() { return vid.female ? GEN_F : GEN_M; } +int lang() { + if(vid.language >= 0) + return vid.language; + return default_language; + } + +int sightrange = 7; + +cell *mouseover, *lmouseover, *centerover, *lcenterover; ld modist, centdist; +string mouseovers; + +int mousex, mousey, mousedist, mousedest, joyx, joyy, joydir, panjoyx, panjoyy; +bool autojoy = true; +hyperpoint mouseh; + +bool leftclick, rightclick, targetclick, hiliteclick; +bool gtouched; +bool revcontrol; + +bool doHighlight() { + return hiliteclick ? vid.monmode == 2 : vid.monmode == 3; + } + +int getcstat; ld getcshift; + +int ZZ; + +string help; + +enum emtype {emNormal, emHelp, emVisual1, emVisual2, + emChangeMode, emCustomizeChar, + emQuit, emDraw, emScores, emPickEuclidean, emPickScores} cmode; + +int andmode = 0; + +int darken = 0; + +#ifndef MOBILE +int& qpixel(SDL_Surface *surf, int x, int y) { + if(x<0 || y<0 || x >= surf->w || y >= surf->h) return ZZ; + char *p = (char*) surf->pixels; + p += y * surf->pitch; + int *pi = (int*) (p); + return pi[x]; + } + +int qpixel3(SDL_Surface *surf, int x, int y) { + if(x<0 || y<0 || x >= surf->w || y >= surf->h) return ZZ; + char *p = (char*) surf->pixels; + p += y * surf->pitch; + p += x; + int *pi = (int*) (p); + return pi[0]; + } + +void loadfont(int siz) { + if(!font[siz]) { + font[siz] = TTF_OpenFont("DejaVuSans-Bold.ttf", siz); + if (font[siz] == NULL) { + printf("error: Font file not found\n"); + exit(1); + } + } + } + +int textwidth(int siz, const string &str) { + if(size(str) == 0) return 0; + + loadfont(siz); + + int w, h; + TTF_SizeUTF8(font[siz], str.c_str(), &w, &h); + // printf("width = %d [%d]\n", w, size(str)); + return w; + } +#endif + +#ifdef IOS + +int textwidth(int siz, const string &str) { + return mainfont->getSize(str, siz / 36.0).width; + } + +#endif + +int darkened(int c) { + for(int i=0; i>= 1; + return c; + } + +int darkenedby(int c, int lev) { + for(int i=0; i>= 1; + return c; + } + +int darkena(int c, int lev, int a) { + for(int i=0; i>= 1; + return (c << 8) + a; + } + +#ifdef GL + +int lalpha = 0xFF; + +void glcolor(int color) { + unsigned char *c = (unsigned char*) (&color); + glColor4f(c[2] / 255.0, c[1] / 255.0, c[0]/255.0, lalpha / 255.0); // c[3]/255.0); + } + +void selectEyeGL(int ed) { + float ve = ed*vid.eye; + ve *= 2; // vid.xres; ve /= vid.radius; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + float lowdepth = 0.1; + float hidepth = 10000; + + // simulate glFrustum + GLfloat frustum[16] = { + vid.yres * 1./vid.xres, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -(hidepth+lowdepth)/(hidepth-lowdepth), -1, + 0, 0, -2*lowdepth*hidepth/(hidepth-lowdepth), 0}; + + if(ve) + glTranslatef(-(ve * vid.radius) * (vid.alpha - (vid.radius*1./vid.xres) * vid.eye) / vid.xres, 0, 0); + + glTranslatef((vid.xcenter*2.)/vid.xres - 1, 1 - (vid.ycenter*2.)/vid.yres, 0); + + glMultMatrixf(frustum); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + float sc = vid.radius / (vid.yres/2.); + GLfloat mat[16] = {sc,0,0,0, 0,-sc,0,0, 0,0,-1,0, 0,0,-vid.alpha,1}; + glMultMatrixf(mat); + + if(ve) glTranslatef(ve, 0, vid.eye); + + vid.scrdist = -vid.alpha + vid.yres * sc / 2; + } + +void selectEyeMask(int ed) { + if(ed == 0) { + glColorMask( GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE ); + } + else if(ed == 1) { + glColorMask( GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE ); + } + else if(ed == -1) { + glColorMask( GL_FALSE,GL_TRUE,GL_TRUE,GL_TRUE ); + } + } + +void setGLProjection() { + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + selectEyeGL(0); + } + +GLfloat glcoords[1500][3]; +int qglcoords; + +bool GL_initialized = false; +void buildpolys(); + +#ifndef MOBILE + +struct glfont_t { + GLuint * textures; // Holds The Texture Id's +//GLuint list_base; // Holds The First Display List ID + int widths[128+NUMEXTRA]; + int heights[128+NUMEXTRA]; + float tx[128+NUMEXTRA]; + float ty[128+NUMEXTRA]; + }; + +glfont_t *glfont[256]; + +void init(const char * fname, unsigned int h); + +inline int next_p2 (int a ) +{ + int rval=1; + // rval<<=1 Is A Prettier Way Of Writing rval*=2; + while(rvalw ); + int theight = next_p2( txt->h ); + + Uint16 expanded_data[twidth * theight]; + + for(int j=0; j =txt->w || j>=txt->h) ? 0 : ((qpixel(txt, i, j)>>24)&0xFF) * 0x101; + } + +// printf("b\n"); + f.widths[ch] = txt->w; + f.heights[ch] = txt->h; + + glBindTexture( GL_TEXTURE_2D, f.textures[ch]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data ); + +// printf("c\n"); + + float x=(float)txt->w / (float)twidth; + float y=(float)txt->h / (float)theight; + f.tx[ch] = x; + f.ty[ch] = y; + +/* glNewList(f.list_base+ch,GL_COMPILE); + glBindTexture(GL_TEXTURE_2D, f.textures[ch]); + + //glPushMatrix(); + + // glTranslatef(bitmap_glyph->left,0,0); + // glTranslatef(0,bitmap_glyph->top-bitmap.rows,0); + +// printf("d\n"); + + glBegin(GL_QUADS); + float eps=0; + glTexCoord2d(eps,eps); glVertex2f(0, txt->h); + glTexCoord2d(eps,y-0); glVertex2f(0, 0); + glTexCoord2d(x-eps,y-0); glVertex2f(txt->w, 0); + glTexCoord2d(x-eps,0); glVertex2f(txt->w, txt->h); + glEnd(); + glEndList(); */ + //glPopMatrix(); + + SDL_FreeSurface(txt); + } + +//printf("init size=%d ok\n", size); + GLERR("initfont"); + } + +int getnext(const char* s, int& i) { + for(int k=0; k= x && mousey <= y && mousex <= x+tsize && mousey >= y-f.heights[32]); + + for(int i=0; s[i];) { + + // glListBase(f.list_base); + // glCallList(s[i]); // s[i]); + + int tabid = getnext(s,i); + float fx=f.tx[tabid]; + float fy=f.ty[tabid]; + int wi = f.widths[tabid]; + int hi = f.heights[tabid]; + + for(int ed = (vid.goteyes && shift)?-1:0; ed<2; ed+=2) { + glPushMatrix(); + glTranslatef(x-ed*shift-vid.xcenter,y-vid.ycenter, vid.scrdist); + selectEyeMask(ed); + glBindTexture(GL_TEXTURE_2D, f.textures[tabid]); + glBegin(GL_QUADS); + glTexCoord2d(0,0); glVertex2f(0, -hi); + glTexCoord2d(0,fy); glVertex2f(0, 0); + glTexCoord2d(fx,fy); glVertex2f(wi, 0); + glTexCoord2d(fx,0); glVertex2f(wi, -hi); + glEnd(); + glPopMatrix(); + } + + if(vid.goteyes) selectEyeMask(0); + + GLERR("print"); + + // int tabid = s[i]; + x += f.widths[tabid]; + +/* + printf("point %d,%d\n", x, y); + glBegin(GL_POINTS); + glVertex3f(rand() % 100 - rand() % 100, rand() % 100 - rand() % 100, 100); + glEnd(); */ + + } + + glDisable(GL_TEXTURE_2D); + + return clicked; + // printf("gl_print ok\n"); + } +#endif + +void resetGL() { + GL_initialized = false; +#ifndef MOBILE + for(int i=0; i<128; i++) if(glfont[i]) { + delete glfont[i]; + glfont[i] = NULL; + } +#endif + buildpolys(); + } + +#endif + +#ifndef MOBILE +bool displaystr(int x, int y, int shift, int size, const char *str, int color, int align) { + + if(strlen(str) == 0) return false; + + if(size <= 0 || size > 255) { + // printf("size = %d\n", size); + return false; + } + +#ifdef GL + if(vid.usingGL) return gl_print(x, y, shift, size, str, color, align); +#endif + + SDL_Color col; + col.r = (color >> 16) & 255; + col.g = (color >> 8 ) & 255; + col.b = (color >> 0 ) & 255; + + col.r >>= darken; col.g >>= darken; col.b >>= darken; + + loadfont(size); + + SDL_Surface *txt = (vid.usingAA?TTF_RenderText_Blended:TTF_RenderText_Solid)(font[size], str, col); + + if(txt == NULL) return false; + + SDL_Rect rect; + + rect.w = txt->w; + rect.h = txt->h; + + rect.x = x - rect.w * align / 16; + rect.y = y - rect.h/2; + + bool clicked = (mousex >= rect.x && mousey >= rect.y && mousex <= rect.x+rect.w && mousey <= rect.y+rect.h); + + if(shift) { + SDL_Surface* txt2 = SDL_DisplayFormat(txt); + SDL_LockSurface(txt2); + SDL_LockSurface(s); + int c0 = qpixel(txt2, 0, 0); + for(int yy=0; yy graphdata; + +void gdpush(int t) { + graphdata.push_back(t); + } + +bool displaychr(int x, int y, int shift, int size, char chr, int col) { + gdpush(2); gdpush(x); gdpush(y); gdpush(8); + gdpush(col); gdpush(size); gdpush(0); + gdpush(1); gdpush(chr); + return false; + } + +void gdpush_utf8(const string& s) { + int g = graphdata.size(), q = 0; + gdpush((int) s.size()); for(int i=0; i= 192 && uch < 224) { + int u = ((s[i] - 192)&31) << 6; + i++; + u += (s[i] - 128) & 63; + gdpush(u); q++; + } + else { + gdpush(s[i]); q++; + } + } + graphdata[g] = q; + } + +bool displayfr(int x, int y, int b, int size, const string &s, int color, int align) { + gdpush(2); gdpush(x); gdpush(y); gdpush(align); + gdpush(color); gdpush(size); gdpush(b); + gdpush_utf8(s); + int mx = x - mousex; + int my = y - mousey; + return + mx >= -3*size && mx <= +3*size && + my >= -size*3/4 && my <= +size*3/4; + } + +bool displaystr(int x, int y, int shift, int size, const string &s, int color, int align) { + gdpush(2); gdpush(x); gdpush(y); gdpush(align); + gdpush(color); gdpush(size); gdpush(0); + gdpush_utf8(s); + int mx = x - mousex; + int my = y - mousey; + return + mx >= -3*size && mx <= +3*size && + my >= -size*3/4 && my <= +size*3/4; + } + +#endif + +bool displaynum(int x, int y, int shift, int size, int col, int val, string title) { + char buf[64]; + sprintf(buf, "%d", val); + bool b1 = displayfr(x-8, y, 1, size, buf, col, 16); + bool b2 = displayfr(x, y, 1, size, title, col, 0); + if((b1 || b2) && gtouched) { + col ^= 0x00FFFF; + displayfr(x-8, y, 1, size, buf, col, 16); + displayfr(x, y, 1, size, title, col, 0); + } + return b1 || b2; + } + +struct msginfo { + int stamp; + char flashout; + char spamtype; + string msg; + }; + +vector msgs; + +vector gamelog; + +void flashMessages() { + for(int i=0; i .9999) return Hypc; + + // hz*hz-(hx/(hz+alpha))^2 - (hy/(hz+alpha))^2 = + + // hz*hz-hr*(hz+alpha)^2 == 1 + // hz*hz - hr*hr*hz*Hz + + ld A = 1-hr; + ld B = 2*hr*vid.alphax; + ld C = 1 + hr*vid.alphax*vid.alphax; + + // Az^2 - Bz = C + B /= A; C /= A; + + // z^2 - Bz = C + // z^2 - Bz + (B^2/4) = C + (B^2/4) + // z = (B/2) + sqrt(C + B^2/4) + + ld hz = B / 2 + sqrt(C + B*B/4); + hyperpoint H; + H[0] = hx * (hz+vid.alphax); + H[1] = hy * (hz+vid.alphax); + H[2] = hz; + + return H; + } + +void getcoord(const hyperpoint& H, int& x, int& y, int &shift) { + + if(H[2] < 0.999) { + printf("error: %s\n", display(H)); + // exit(1); + } + ld tz = euclid ? (EUCSCALE+vid.alphax) : vid.alphax+H[2]; + if(tz < 1e-3 && tz > -1e-3) tz = 1000; + x = vid.xcenter + int(vid.radius * H[0] / tz); + y = vid.ycenter + int(vid.radius * H[1] / tz); +#ifndef MOBILE + shift = vid.goteyes ? int(vid.eye * vid.radius * (1 - vid.beta / tz)) : 0; +#endif + } + +int dlit; + +int polyi; + +#define POLYMAX 60000 + +#ifdef MOBILE +short polyx[POLYMAX], polyy[POLYMAX]; +#else +Sint16 polyx[POLYMAX], polyxr[POLYMAX], polyy[POLYMAX]; +#endif + +void drawline(const hyperpoint& H1, int x1, int y1, int s1, const hyperpoint& H2, int x2, int y2, int col) { + dlit++; if(dlit>500) return; + + int dst = (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); + + #ifdef GL + if(vid.usingGL && dst <= (ISMOBILE ? 100 : 20)) { + if(euclid) { + for(int i=0; i<2; i++) glcoords[qglcoords][i] = H1[i]; glcoords[qglcoords][2] = EUCSCALE; + } + else { + for(int i=0; i<3; i++) glcoords[qglcoords][i] = H1[i]; + } + qglcoords++; + return; + } + #endif + + #ifdef MOBILE + if(dst <= 400 && !vid.usingGL) { + if(polyi >= POLYMAX) return; + polyx[polyi] = x1; + polyy[polyi] = y1; + polyi++; + return; + } + #else + #ifdef GFX + if(dst <= 20 && !vid.usingGL) { + if(col == -1) { + if(polyi >= POLYMAX) return; + polyx[polyi] = x1-s1; + polyxr[polyi] = x1+s1; + polyy[polyi] = y1; + polyi++; + } + else (vid.usingAA?aalineColor:lineColor) (s, x1, y1, x2, y2, col); + return; + } + #endif + if(dst <= 2) { + return; + } + #endif + + hyperpoint H3 = mid(H1, H2); + int x3, y3, s3; getcoord(H3, x3, y3, s3); + #ifndef GFX + if(!vid.usingGL) { + qpixel(s, x3-s3, y3) |= col & 0xFF0000; + qpixel(s, x3+s3, y3) |= col & 0x00FFFF; + } + #endif + + drawline(H1, x1, y1, s1, H3, x3, y3, col); + drawline(H3, x3, y3, s3, H2, x2, y2, col); + } + +void drawline(const hyperpoint& H1, const hyperpoint& H2, int col) { + if(vid.usingGL) { + qglcoords = 0; + } + + // printf("line\n"); + if(col != -1) { + col = (col << 8) + lalpha; + if(col == -1) col = -2; + polyi = 0; + #ifndef GFX + if(!vid.usingGL) { + SDL_LockSurface(s); + col >>= 8; + } + #endif + } + + dlit = 0; + int x1, y1, s1; getcoord(H1, x1, y1, s1); + int x2, y2, s2; getcoord(H2, x2, y2, s2); + drawline(H1, x1, y1, s1, H2, x2, y2, col); + + if(vid.usingGL) { + + // EUCLIDEAN + if(euclid) { + for(int i=0; i<2; i++) glcoords[qglcoords][i] = H2[i]; glcoords[qglcoords][2] = EUCSCALE; + } + else { + for(int i=0; i<3; i++) glcoords[qglcoords][i] = H2[i]; + } + qglcoords++; + + glVertexPointer(3, GL_FLOAT, 0, glcoords); + glEnableClientState(GL_VERTEX_ARRAY); + glcolor(col >> 8); + + if(vid.goteyes) { + selectEyeGL(-1); + selectEyeMask(-1); + glDrawArrays(GL_LINE_STRIP, 0, qglcoords); + selectEyeGL(+1); + selectEyeMask(+1); + glDrawArrays(GL_LINE_STRIP, 0, qglcoords); + selectEyeGL(0); + selectEyeMask(0); + } + else glDrawArrays(GL_LINE_STRIP, 0, qglcoords); + } + + #ifdef MOBILE + else if(col != -1) { + gdpush(3); gdpush(col); + gdpush(polyi+1); + for(int i=0; itype; + } + +int gradient(int c0, int c1, ld v0, ld v, ld v1) { + int vv = int(256 * ((v-v0) / (v1-v0))); + int c = 0; + for(int a=0; a<3; a++) { + int p0 = (c0 >> (8*a)) & 255; + int p1 = (c1 >> (8*a)) & 255; + int p = (p0*(256-vv) + p1*vv + 127) >> 8; + c += p << (8*a); + } + return c; + } + +// cloak color +int cloakcolor(int rtr) { + rtr -= 28; + rtr /= 2; + rtr %= 10; + if(rtr < 0) rtr += 10; + // rtr = time(NULL) % 10; + int cc[10] = { + 0x8080FF, 0x80FFFF, 0x80FF80, 0xFF8080, 0xFF80FF, 0xFFFF80, + 0xFFFFC0, 0xFFD500, 0x421C52, 0 + }; + return cc[rtr]; + } + +int firecolor(int phase) { + return gradient(0xFFFF00, 0xFF0000, -1, sin((phase + ticks)/100.0), 1); + } + +int fc(int ph, int col) { + if(items[itOrbFire]) col = darkena(firecolor(ph), 0, 0xFF); + if(items[itOrbGhost]) col = (col &~0XFF) | (col&0xFF) / 2; + if(invismove) col = (col &~0XFF) | (int((col&0xFF) * (100+100*sin(ticks / 500.)))/200); + return col; + } + +int flashat, lightat, safetyat; +cell *flashcell; + +void drawFlash(cell *c) { flashat = ticks; flashcell = c; } +void drawLightning() { lightat = ticks; } +void drawSafety() { safetyat = ticks; } + +#include "polygons.cpp" + +bool drawplayer = true; + +transmatrix playertrans; + +double eurad = 0.52; + +bool outofmap(hyperpoint h) { + if(euclid) + return h[0] * h[0] + h[1] * h[1] > 15 * eurad; + else + return h[2] < .5; + } + +void drawShield(const transmatrix& V) { + float ds = ticks / 300.; + int col = darkened(iinf[itOrbShield].color); + for(int a=0; a<84*5; a++) + drawline(V*ddi(a, hexf + sin(ds + M_PI*2*a/20)*.1)*C0, V*ddi((a+1), hexf + sin(ds + M_PI*2*(a+1)/20)*.1)*C0, col); + } + +void drawSpeed(const transmatrix& V) { + ld ds = ticks / 10.; + int col = darkened(iinf[itOrbSpeed].color); + for(int b=0; b<84; b+=14) + for(int a=0; a<84; a++) + drawline(V*ddi(ds+b+a, hexf*a/84)*C0, V*ddi(ds+b+(a+1), hexf*(a+1)/84)*C0, col); + } + +void drawSafety(const transmatrix& V, int ct) { + ld ds = ticks / 50.; + int col = darkened(iinf[itOrbSafety].color); + for(int a=0; atype; + else + return 42 - d * 84 / c->type; + } + +bool drawMonster(const transmatrix& V, int ct, cell *c, int col) { + + if(doHighlight()) + poly_outline = + (c->cpdist == 0 || isFriendly(c)) ? 0x00FF00FF : 0xFF0000FF; + + eMonster m = c->monst; + + if(c->cpdist == 0) { + + if(items[itOrbShield] > 1) drawShield(V); + + if(items[itOrbSpeed]) drawSpeed(V); + + int ct = c->type; + + if(items[itOrbSafety]) drawSafety(V, ct); + + if(items[itOrbFlash]) drawFlash(V); + + if(items[itOrbWinter]) + drawWinter(V, displaydir(c, cwt.spin)); + + if(items[itOrbLightning] > 1) drawLightning(V); + + if(safetyat > 0) { + int tim = ticks - safetyat; + if(tim > 2500) safetyat = 0; + for(int u=tim; u<=2500; u++) { + if((u-tim)%250) continue; + ld rad = hexf * u / 250; + int col = iinf[itOrbSafety].color; + for(int a=0; a<84; a++) + drawline(V*ddi(a, rad)*C0, V*ddi(a+1, rad)*C0, col); + } + } + + transmatrix cV2 = c == cwt.c ? cwtV : V; + // if(flipplayer) cV2 = cV2 * spin(M_PI); + if(flipplayer) cV2 = cV2 * spin(M_PI); + + if(vid.monmode < 2) return true; + + bool havus = shUser[0][2].s; + playertrans = cV2; + + for(int i=0; i<8; i++) if(shUser[i][2].s) + queuepoly(cV2, ct, shUser[i][2], 0xFFFFFFFF); + + if(drawplayer && !havus) { + + if(c->monst == moGolem) { + queuepoly(cV2, ct, shPBody, darkena(col, 0, 0XC0)); + queuepoly(cV2, ct, shGolemhead, darkena(col, 1, 0XFF)); + } + else { + queuepoly(cV2, ct, vid.female ? shFemaleBody : shPBody, fc(0, vid.skincolor)); + + if(items[itOrbThorns]) + queuepoly(cV2, ct, shHedgehogBladePlayer, 0x00FF00FF); + else + queuepoly(cV2, ct, shPSword, fc(314, vid.swordcolor)); + + if(cheater) { + queuepoly(cV2, ct, shDemon, darkena(0xFFFF00, 0, 0xFF)); + // queuepoly(cV2, ct, shHood, darkena(0xFF00, 1, 0xFF)); + } + else { + queuepoly(cV2, ct, shPFace, fc(500, vid.skincolor)); + queuepoly(cV2, ct, vid.female ? shFemaleHair : shPHead, fc(150, vid.haircolor)); + } + if(vid.female) + queuepoly(cV2, ct, shFemaleDress, fc(500, vid.dresscolor)); + + if(knighted) + queuepoly(cV2, ct, shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); + } + } + } + + if(isIvy(c) || isWorm(c)) { + + transmatrix V2 = V; + + if(c->mondir != NODIR) { + int hdir = displaydir(c, c->mondir); + + if(vid.monmode > 1) { + V2 = V2 * spin(hdir * M_PI / 42); + if(isIvy(c)) + queuepoly(V2, ct, shIBranch, (col << 8) + 0xFF); + else if(c->monst < moTentacle) { + queuepoly(V2, ct, shTentacleX, 0xFF); + queuepoly(V2, ct, shTentacle, (col << 8) + 0xFF); + } + else { + queuepoly(V2, ct, shTentacleX, 0xFFFFFFFF); + queuepoly(V2, ct, shTentacle, (col << 8) + 0xFF); + } + } + + else for(int u=-1; u<=1; u++) + drawline(V*ddi(hdir+21, u*crossf/5)*C0, V*ddi(hdir, crossf)*ddi(hdir+21, u*crossf/5)*C0, 0x606020 >> darken); + } + + if(vid.monmode > 1) { + if(isIvy(c)) + queuepoly(V, ct, shILeaf[ct-6], darkena(col, 0, 0xFF)); + else if(m == moWorm || m == moWormwait) { + queuepoly(V2 * spin(M_PI), ct, shWormHead, darkena(col, 0, 0xFF)); + queuepoly(V2 * spin(M_PI), ct, shEyes, 0xFF); + } + else if(m == moTentacle || m == moTentaclewait || m == moTentacleEscaping) + queuepoly(V2 * spin(M_PI), ct, shTentHead, darkena(col, 0, 0xFF)); + else + queuepoly(V2, ct, shJoint, darkena(col, 0, 0xFF)); + } + + return vid.monmode < 2; + } + + else if(isMimic(c)) { + + int hdir = displaydir(c, c->mondir); + + transmatrix mirrortrans = Id; + if(c->monst == moMirror) mirrortrans[1][1] = -1; + transmatrix V2 = V * spin(M_PI*hdir/42) * mirrortrans; + + if(vid.monmode > 1) { + if(flipplayer) V2 = V2 * spin(M_PI); + queuepoly(V2, ct, vid.female ? shFemaleBody : shPBody, darkena(col, 0, 0X80)); + queuepoly(V2, ct, shPSword, darkena(col, 0, 0XC0)); + queuepoly(V2, ct, vid.female ? shFemaleHair : shPHead, darkena(col, 1, 0XC0)); + queuepoly(V2, ct, shPFace, darkena(col, 0, 0XC0)); + if(vid.female) + queuepoly(V2, ct, shFemaleDress, darkena(col, 1, 0XC0)); + if(flipplayer) V2 = V2 * spin(M_PI); + } + + if(!outofmap(mouseh)) { + hyperpoint P2 = V2 * inverse(cwtV) * mouseh; + int xc, yc, sc; + getcoord(P2, xc, yc, sc); + displaychr(xc, yc, sc, 10, 'x', 0xFF00); + } + + return vid.monmode < 2; + } + + else if(c->monst == moIllusion) { + if(vid.monmode > 1) { + queuepoly(V, ct, vid.female ? shFemaleBody : shPBody, darkena(col, 0, 0X80)); + queuepoly(V, ct, shPSword, darkena(col, 0, 0XC0)); + queuepoly(V, ct, vid.female ? shFemaleHair : shPHead, darkena(col, 1, 0XC0)); + queuepoly(V, ct, shPFace, darkena(col, 0, 0XC0)); + if(vid.female) + queuepoly(V, ct, shFemaleDress, darkena(col, 1, 0XC0)); + } + return vid.monmode < 2; + } + + else if(c->monst && vid.monmode < 2) return true; + + else if(isFriendly(c)) { + // golems and knights don't face player + int hdir = displaydir(c, c->mondir) + 42; + transmatrix V2 = V * spin(hdir * M_PI / 42) ; + if(m == moKnight) { + queuepoly(V2, ct, shPBody, darkena(0xC0C0A0, 0, 0xC0)); + queuepoly(V2, ct, shPSword, darkena(0xFFFF00, 0, 0xFF)); + queuepoly(V2, ct, shKnightArmor, darkena(0xD0D0D0, 1, 0xFF)); + int col; + if(c->master->alt) + col = cloakcolor(roundTableRadius(c)); + else + col = cloakcolor(newRoundTableRadius()); + queuepoly(V2, ct, shKnightCloak, darkena(col, 1, 0xFF)); + queuepoly(V2, ct, shPHead, darkena(0x703800, 1, 0XFF)); + queuepoly(V2, ct, shPFace, darkena(0xC0C0A0, 0, 0XFF)); + } + else { + queuepoly(V2, ct, shPBody, darkena(col, 0, 0XC0)); + queuepoly(V2, ct, shGolemhead, darkena(col, 1, 0XFF)); + } + } + + else if(c->monst) { + + // face the player + transmatrix VL; + + if(false) { + // hyperpoint V0 = cwtV * C0; + hyperpoint V1 = V * C0; + VL = V * spin(hypot(V1[0], V1[1])); + } + else { + hyperpoint V0 = inverse(cwtV) * V * C0; + hyperpoint V1 = spintox(V0) * V0; + VL = cwtV * rspintox(V0) * rpushxto0(V1) * spin(M_PI); + } + + char xch = minf[m].glyph; + + if(m == moWolf) { + queuepoly(VL, ct, shWolfLegs, darkena(col, 0, 0xFF)); + queuepoly(VL, ct, shWolfBody, darkena(col, 0, 0xFF)); + queuepoly(VL, ct, shWolfHead, darkena(col, 0, 0xFF)); + queuepoly(VL, ct, shWolfEyes, darkena(col, 3, 0xFF)); + } + else if(m == moVineBeast) { + queuepoly(VL, ct, shWolfLegs, 0x00FF00FF); + queuepoly(VL, ct, shWolfBody, darkena(col, 1, 0xFF)); + queuepoly(VL, ct, shWolfHead, darkena(col, 0, 0xFF)); + queuepoly(VL, ct, shWolfEyes, 0xFF0000FF); + } + else if(isBug(m)) { + + int hdir = displaydir(c, c->mondir) + 42; + + transmatrix V2 = V * spin(hdir * M_PI / 42) ; + + queuepoly(V2, ct, shBugBody, darkena(col, 0, 0xFF)); + queuepoly(V2, ct, shBugArmor, darkena(col, 1, 0xFF)); + } + else if(m == moRunDog) { + queuepoly(VL, ct, shWolf, darkena(col, 0, 0xFF)); + } + else if(m == moShark || m == moGreaterShark) + queuepoly(VL, ct, shShark, darkena(col, 0, 0xFF)); + else if(m == moEagle) + queuepoly(VL, ct, shEagle, darkena(col, 0, 0xFF)); + else if(m == moZombie) + queuepoly(VL, ct, shPBody, darkena(col, 0, 0xFF)); + else if(m == moDesertman) { + queuepoly(VL, ct, shPBody, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPSword, 0xFFFF00FF); + queuepoly(VL, ct, shHood, 0xD0D000C0); + } + else if(m == moCrystalSage) { + queuepoly(VL, ct, shPBody, 0xFFFFFFFF); + queuepoly(VL, ct, shPHead, 0xFFFFFFFF); + queuepoly(VL, ct, shPFace, 0xFFFFFFFF); + } + else if(m == moHedge) { + queuepoly(VL, ct, shPBody, darkena(col, 0, 0xFF)); + queuepoly(VL, ct, shHedgehogBlade, 0xC0C0C0FF); + queuepoly(VL, ct, shPHead, 0x804000FF); + queuepoly(VL, ct, shPFace, 0xF09000FF); + } + else if(m == moYeti || m == moMonkey) { + queuepoly(VL, ct, shYeti, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPHead, darkena(col, 0, 0xFF)); + } + else if(m == moShadow) { + queuepoly(VL, ct, shPBody, darkena(col, 0, 0X80)); + queuepoly(VL, ct, shPSword, darkena(col, 0, 0XC0)); + queuepoly(VL, ct, shPHead, darkena(col, 1, 0XC0)); + queuepoly(VL, ct, shPFace, darkena(col, 0, 0XC0)); + } + else if(m == moRanger) { + queuepoly(VL, ct, shPBody, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPSword, darkena(col, 0, 0xFF)); + queuepoly(VL, ct, shArmor, darkena(col, 1, 0xFF)); + } + else if(m == moGhost || m == moSeep) { + queuepoly(VL, ct, shGhost, darkena(col, 0, 0x80)); + queuepoly(VL, ct, shEyes, 0xFF); + } + else if(m == moVineSpirit) { + queuepoly(VL, ct, shGhost, 0xD0D0D0C0); + queuepoly(VL, ct, shEyes, 0xFF0000FF); + } + else if(m == moFireFairy) { + col = firecolor(0); + queuepoly(VL, ct, shFemaleBody, darkena(col, 0, 0XC0)); +// queuepoly(cV2, ct, shPSword, darkena(col, 0, 0XFF)); + queuepoly(VL, ct, shFemaleHair, darkena(col, 1, 0xFF)); + queuepoly(VL, ct, shPFace, darkena(col, 0, 0XFF)); +// queuepoly(cV2, ct, shFemaleDress, 0xC00000FF); + } + else if(m == moSlime) { + queuepoly(VL, ct, shSlime, darkena(col, 0, 0x80)); + queuepoly(VL, ct, shEyes, 0xFF); + } + else if(m == moCultist || m == moPyroCultist || m == moCultistLeader) { + queuepoly(VL, ct, shPBody, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPSword, darkena(col, 2, 0xFF)); + queuepoly(VL, ct, shHood, darkena(col, 1, 0xFF)); + } + else if(m == moNecromancer) { + queuepoly(VL, ct, shPBody, 0xC00000C0); + queuepoly(VL, ct, shHood, darkena(col, 1, 0xFF)); + } + else if(m == moGoblin) { + queuepoly(VL, ct, shYeti, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shArmor, darkena(col, 1, 0XFF)); + } + else if(m == moLancer || m == moFlailer || m == moMiner) { + if(m == moLancer) + VL = VL * spin(c->type == 6 ? -M_PI/3 : -M_PI/2 ); + queuepoly(VL, ct, shPBody, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, m == moFlailer ? shArmor : shHood, darkena(col, 1, 0XFF)); + if(m == moMiner) + queuepoly(VL, ct, shPickAxe, darkena(0xC0C0C0, 0, 0XFF)); + if(m == moLancer) + queuepoly(VL, ct, shPike, darkena(col, 0, 0XFF)); + if(m == moFlailer) { + queuepoly(VL, ct, shFlailBall, darkena(col, 0, 0XFF)); + queuepoly(VL, ct, shFlailChain, darkena(col, 1, 0XFF)); + queuepoly(VL, ct, shFlailTrunk, darkena(col, 0, 0XFF)); + } + } + else if(m == moTroll) { + queuepoly(VL, ct, shYeti, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPHead, darkena(col, 1, 0XFF)); + queuepoly(VL, ct, shPFace, darkena(col, 2, 0XFF)); + } + else if(m == moDarkTroll) { + queuepoly(VL, ct, shYeti, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPHead, darkena(col, 0, 0XFF)); + queuepoly(VL, ct, shPFace, 0xFFFFFF80); + } + else if(m == moEarthElemental) { + queuepoly(VL, ct, shYeti, darkena(col, 0, 0xC0)); + queuepoly(VL, ct, shPHead, darkena(col, 0, 0XFF)); + queuepoly(VL, ct, shPFace, 0xF0000080); + } + else if(xch == 'd' || xch == 'D') { + queuepoly(VL, ct, shPBody, darkena(col, 1, 0xC0)); + int acol = col; + if(xch == 'D') acol = 0xD0D0D0; + queuepoly(VL, ct, shDemon, darkena(acol, 0, 0xFF)); + } + else if(m == moEvilGolem) { + queuepoly(VL, ct, shPBody, darkena(col, 0, 0XC0)); + queuepoly(VL, ct, shGolemhead, darkena(col, 1, 0XFF)); + } + else if(isWitch(m)) { + int c = 0xFF; + if(m == moWitchGhost) c = 0x85 + 120 * sin(ticks / 160.0); + if(m == moWitchWinter) drawWinter(VL, 42); + if(m == moWitchFlash) drawFlash(VL); + if(m == moWitchSpeed) drawSpeed(VL); + if(m == moWitchFire) col = firecolor(0); + queuepoly(VL, ct, shFemaleBody, darkena(col, 0, c)); +// queuepoly(cV2, ct, shPSword, darkena(col, 0, 0XFF)); +// queuepoly(VL, ct, shHood, darkena(col, 0, 0XC0)); + if(m == moWitchFire) col = firecolor(100); + queuepoly(VL, ct, shFemaleHair, darkena(col, 1, c)); + if(m == moWitchFire) col = firecolor(200); + queuepoly(VL, ct, shPFace, darkena(col, 0, c)); + if(m == moWitchFire) col = firecolor(300); + queuepoly(VL, ct, shWitchDress, darkena(col, 1, 0XC0)); + } + else return true; + } + + return false; + } + +cell *keycell; +int keycelldist; + +void drawCircle(int x, int y, int size, int color) { + #ifdef GL + if(vid.usingGL) { + qglcoords = 0; + glcolor(color); + x -= vid.xcenter; y -= vid.ycenter; + int pts = size * 4; + if(pts > 1500) pts = 1500; + if(ISMOBILE && pts > 72) pts = 72; + for(int r=0; r 1500) pts = 1500; + for(int r=0; rtype; t++) if(c->mov[t] && bugsNearby(c->mov[t], dist-1)) return true; + return false; + } + +void drawcell(cell *c, transmatrix V, int spinv) { + + // todo: fix when scrolling + if(c->land != laGameBoard && sightrange < 10) { + // not yet created + if(c->mpdist > 7) return; + // (incorrect comment) too far, no bugs nearby + if(playermoved && c->cpdist > sightrange) return; + } + + if(!euclid) { + // draw a web-like map + if(webdisplay & 1) { + if(c->type == 6) { + for(int a=0; a<3; a++) + drawline(V*Crad[a*7], V*Crad[a*7+21], 0xd0d0 >> darken); + } + else { + for(int a=0; a<7; a++) + drawline(V*C0, V*Crad[(21+a*6)%42], 0xd0d0 >> darken); + } + } + + if(webdisplay & 2) if(c->type == 7) { + drawline(V*C0, V*xpush(tessf)*C0, 0xd0d0 >> darken); + } + + if(webdisplay & 4) if(c->type == 7 && c->master->alt) { + for(int i=0; i<7; i++) + if(c->master->move[i]->alt == c->master->alt->move[0]) + drawline(V*C0, V*spin(-2*M_PI*i/7)*xpush(tessf)*C0, 0xd000d0 >> darken); + } + } + + // save the player's view center + if(c == cwt.c) { + playerfound = true; + +/* if(euclid) + return d * 84 / c->type; + else + return 42 - d * 84 / c->type; + cwtV = V * spin(-cwt.spin * 2*M_PI/c->type) * spin(M_PI); */ + + cwtV = V * spin(displaydir(c, cwt.spin) * M_PI/42); + } + + if(1) { + + hyperpoint VC0 = V*C0; + + if(intval(mouseh, VC0) < modist) { + modist = intval(mouseh, VC0); + mouseover = c; + } + + double dfc = euclid ? intval(VC0, C0) : VC0[2]; + + if(dfc < centdist) { + centdist = dfc; + centerover = c; + } + + int xc, yc, sc, xs, ys, ss; + getcoord(VC0, xc, yc, sc); + getcoord(V*xpush(.5)*C0, xs, ys, ss); + // int col = 0xFFFFFF - 0x20 * c->maxdist - 0x2000 * c->cpdist; + + if(c->mpdist > 8) return; // not yet generated + + char ch = winf[c->wall].glyph; + int col = winf[c->wall].color; + + if(c->land == laAlchemist && c->wall == waNone) col = 0x202020; + + if(c->land == laCrossroads && c->wall == waNone) col = (vid.goteyes ? 0xFF3030 : 0xFF0000); + if(c->land == laDesert && c->wall == waNone) col = 0xEDC9AF; + if(c->land == laCaves && c->wall == waNone) col = 0x202020; + if(c->land == laFjord && c->wall == waNone) col = 0x202020; + if(c->land == laDeadCaves && c->wall == waNone) col = 0x202020; + if(isHive(c->land)) { + col = linf[c->land].color; + if(c->wall == waWaxWall) + col = int(c->heat) & 0xFFFFFF; + } + if(c->land == laJungle && c->wall == waNone) col = (vid.goteyes ? 0x408040 : 0x008000); + if(c->land == laPower && c->wall == waNone) + col = linf[c->land].color; +/* if(c->land == laFjord && c->wall == waNone) { + col = 0x50A020; + } + if(c->land == laFjord && c->wall == waLake) { + col = 0x202080; + int i = 0; + for(int k=0; ktype; k++) if(c->mov[k] && c->mov[k]->wall != waLake) + i++; + if(i > 0) { + col = gradient(col, 0xFFFFFF, 0, i-fabs(sin(ticks/1500.0)), 7); + } + } */ + if(c->land == laWineyard && c->wall == waNone) { + col = 0x006000; + } + if(c->land == laDryForest && c->wall == waNone) { + if(c->wall == waDryTree) + col = (vid.goteyes ? 0xC0C060 : 0xC0C000); + else if(c->wall == waWetTree) + col = (vid.goteyes ? 0x60C060 : 0x00C000); + else if(c->wall == waNone) { + col = gradient(0x008000, 0x800000, 0, c->heat, 10); + } + } + if(c->land == laMirror && c->wall == waNone) col = 0x808080; + if(c->land == laMotion && c->wall == waNone) col = 0xF0F000; + if(c->land == laGraveyard && c->wall == waNone) col = 0x107010; + if(c->land == laCamelot && c->wall == waNone) { + int d = showoff ? 0 : celldistAltRelative(c); + if(d < 0) + col = 0xA0A0A0; + else { + // a nice floor pattern + int v = fjordval(c); + int v0 = (v&~3); + bool sw = (v&1); + if(v0 == 8 || v0 == 12 || v0 == 20 || v0 == 40 || v0 == 36 || v0 == 24) + sw = !sw; + if(sw) + col = 0xC0C0C0; + else + col = 0xA0A0A0; + } + } + if(c->land == laRlyeh && c->wall == waNone) col = (vid.goteyes ? 0x4080C0 : 0x004080); + if(c->land == laTemple) { + int d = showoff ? 0 : celldistAlt(c); + if(d % TEMPLE_EACH == 0) + col = c->wall == waColumn ? winf[waColumn].color : + gradient(0x304080, winf[waColumn].color, 0, 0.5, 1); +// else if(c->type == 7) +// col = 0x707070; + else if(d% 2 == -1) + col = 0x304080; + else + col = 0x405090; + } + if(c->land == laHell && c->wall == waNone) col = (vid.goteyes ? 0xC03030 : 0xC00000); + if(c->land == laGameBoard) { + col = linf[c->land].color; + if(c->wall != waNone) + col = winf[c->wall].color; + if(c->wall == waLake) col = 0x202020; + if(c->wall == waFrozenLake) col = 0xC0C0C0; + + if(c->type == 7 && vid.boardmode == '3') col = 0; + if(c->type == 6 && vid.boardmode == '7') col = 0; + } + + if(isIcyLand(c) && isIcyWall(c)) { + if(c->heat < -0.4) + col = gradient(0x4040FF, 0x0000FF, -0.4, c->heat, -1); + else if(c->heat < 0) + col = gradient(0x8080FF, 0x4040FF, 0, c->heat, -0.4); + else if(c->heat < 0.2) + col = gradient(0x8080FF, 0xFFFFFF, 0, c->heat, 0.2); + // else if(c->heat < 0.4) + // col = gradient(0xFFFFFF, 0xFFFF00, 0.2, c->heat, 0.4); + else if(c->heat < 0.6) + col = gradient(0xFFFFFF, 0xFF0000, 0.2, c->heat, 0.6); + else if(c->heat < 0.8) + col = gradient(0xFF0000, 0xFFFF00, 0.6, c->heat, 0.8); + else + col = 0xFFFF00; + if(c->wall == waNone) + col = (col & 0xFEFEFE) >> 1; + if(c->wall == waLake) + col = (col & 0xFCFCFC) >> 2; + } + + if(c->wall == waBonfire && c->tmp == 0) + col = 0x404040; + + if(isFire(c) && c->tmp > 0) + col = firecolor(100); + + if(c->wall == waThumper && c->tmp == 0) + col = 0xEDC9AF; + + if(c->wall == waThumper && c->tmp > 0) { + int ds = ticks; + for(int u=0; u<5; u++) { + ld rad = hexf * (.3 * u + (ds%1000) * .0003); + int col = gradient(0xFFFFFF, 0, 0, rad, 1.5 * hexf); + for(int a=0; a<84; a++) + drawline(V*ddi(a, rad)*C0, V*ddi(a+1, rad)*C0, col); + } + } + + if(c->land == laFjord && c->wall == waCavefloor) { + col = gradient(col, 0xFF00, 0, 0.5, 1); + // col |= 0xFF00; // col += 0x300060; // col += 0x2F18; col -= 0x100000; + } + + if(c->land == laFjord && c->wall == waCavewall) { + col = 0xC0FFC0; + // col |= 0xFF00; // col += 0x300060; // col += 0x2F18; col -= 0x100000; + } + + if(c->land == laHive && items[itOrbInvis] && c->wall == waNone && c->heat) + col = gradient(col, 0xFF0000, 0, c->heat, 100); + + if(vid.darkhepta && ishept(c)) + col = gradient(0, col, 0, 0.75, 1); + + int ycol = col; + + if(c->land == laHive && c->bardir == NOBARRIERS && c->barleft) { + col = minf[moBug0+c->barright].color; + } + + int xcol = col; + + if(c->item) + ch = iinf[c->item].glyph, col = iinf[c->item].color; + + int icol = col; + + if(c->item && c->land == laAlchemist) + xcol = col; + + if(c->monst) + ch = minf[c->monst].glyph, col = minf[c->monst].color; + + if(c->cpdist == 0 && drawplayer) { ch = '@'; col = cheater ? 0xFF3030 : 0xD0D0D0; } + + if(c->monst == moSlime) { + col = winf[c->wall].color; + col |= (col>>1); + } + + if(c->ligon) { + int tim = ticks - lightat; + if(tim > 1000) tim = 800; + for(int t=0; t<7; t++) if(c->mov[t] && c->mov[t]->ligon) { + int hdir = displaydir(c, t); + int col = gradient(iinf[itOrbLightning].color, 0, 0, tim, 1100); + drawline(V*ddi(ticks, hexf/2)*C0, V*ddi(hdir, crossf)*C0, col); + } + } + + int ct = c->type; + + bool error = false; + + if(vid.wallmode) { + + poly_outline = 0x000000FF; + + // floor + + int fd = + c->land == laAlchemist || c->land == laIce || c->land == laGraveyard || + c->land == laRlyeh || c->land == laTemple ? 1 : 2; + + if(shUser[0][ct-6].s) { + for(int i=0; i<8; i++) if(shUser[i][ct-6].s) + queuepoly(V, ct, shUser[i][ct-6], darkena(xcol, 2, 0xC0)); + } + + else if(c->wall == waChasm) + ; + + else if(c->land == laWineyard && (c->wall == waVineHalfA || c-> wall == waVineHalfB)) { + + int i =-1; + for(int t=0;t<6; t++) if(c->mov[t] && c->mov[t]->wall == c->wall) + i = t; + + int hdir = 14 + displaydir(c, i); + + transmatrix V2 = V * spin(M_PI*hdir/42); + + hpcshape *shar = shSemiFeatherFloor; + + if(vid.wallmode == 1) shar = shSemiBFloor; + if(vid.wallmode == 2) shar = shSemiFloor; + + int dk = vid.wallmode == 1 ? 0 : vid.wallmode == 2 ? 2 : 1; + + queuepoly(V2, ct, shar[0], darkena(winf[waVinePlant].color, dk, 0xFF)); + queuepoly(V2, ct, shar[1], darkena(xcol, dk, 0xFF)); + } + + else if(vid.wallmode == 1 && c->land == laAlchemist) + queuepoly(V, ct, shFloor[ct-6], darkena(xcol, 1, 0xFF)); + + else if(vid.wallmode == 1 && c->land != laGameBoard) + queuepoly(V, ct, shBFloor[ct-6], darkena(xcol, 0, 0xFF)); + + else if(vid.wallmode == 2 && c->land != laGameBoard) { + queuepoly(V, ct, shFloor[ct-6], darkena(xcol, fd, 0xFF)); + } + + else if(c->land == laWineyard) { + queuepoly(V, ct, (euclid ? shStarFloor : shFeatherFloor)[ct-6], darkena(xcol, 1, 0xFF)); + } + + else if(c->land == laRlyeh) + queuepoly(V, ct, (euclid ? shFloor: shTriFloor)[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laTemple) + queuepoly(V, ct, (euclid ? shFloor: shTriFloor)[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laAlchemist) + queuepoly(V, ct, shCloudFloor[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laJungle) + queuepoly(V, ct, (euclid ? shStarFloor : shFeatherFloor)[ct-6], darkena(xcol, 2, 0xFF)); + + else if(c->land == laGraveyard) + queuepoly(V, ct, (euclid ? shFloor : shCrossFloor)[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laFjord) { + queuepoly(V, ct, (euclid ? shFloor : shCaveFloor)[ct-6], darkena(xcol, 2, 0xFF)); + } + + else if(c->land == laDeadCaves) { + queuepoly(V, ct, (euclid ? shFloor : shCaveFloor)[ct-6], darkena(xcol, 1, 0xFF)); + } + + else if(c->land == laMotion) + queuepoly(V, ct, shMFloor[ct-6], darkena(xcol, 2, 0xFF)); + + else if(c->land == laHell) + queuepoly(V, ct, (euclid ? shStarFloor : shDemonFloor)[ct-6], darkena(xcol, 2, 0xFF)); + + else if(c->land == laIce) +// queuepoly(V, ct, shFloor[ct-6], darkena(xcol, 2, 0xFF)); + queuepoly(V, ct, shStarFloor[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laCocytus) + queuepoly(V, ct, (euclid ? shCloudFloor : shDesertFloor)[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laPower) + queuepoly(V, ct, (euclid ? shCloudFloor : shPowerFloor)[ct-6], darkena(xcol, 1, 0xFF)); + + else if(c->land == laHive) { + queuepoly(V, ct, shFloor[ct-6], darkena(xcol, 1, 0xFF)); + queuepoly(V, ct, shMFloor[ct-6], darkena(xcol, 2, 0xFF)); + if(c->wall != waWaxWall && c->wall != waDeadTroll && c->wall != waVinePlant) + queuepoly(V, ct, shMFloor2[ct-6], darkena(xcol, xcol==ycol ? 1 : 2, 0xFF)); + } + + else if(c->land == laCaves) + queuepoly(V, ct, (euclid ? shCloudFloor : shCaveFloor)[ct-6], darkena(xcol, 2, 0xFF)); + + else if(c->land == laGameBoard) { + if(c->type == 7 && vid.boardmode == '7') + queuepoly(V, ct, vid.wallmode == 1 ? shBFloor[ct-6] : shBigHepta, darkena(xcol, 2, 0xFF)); + + if(c->type == 6 && vid.boardmode == '3') + queuepoly(V, ct, vid.wallmode == 1 ? shBFloor[ct-6] : shBigTriangle, darkena(xcol, 2, 0xFF)); + + if(vid.boardmode == 'h') + queuepoly(V, ct, vid.wallmode == 1 ? shBFloor[ct-6] : shFloor[c->type - 6], darkena(xcol, 2, 0xFF)); + + if(vid.boardmode == 'f') { + static int fcol[4] = { 0x404040FF, 0xFF000080, 0x008000FF, 0x000080FF }; + int fv = fjordval(c); + col = fcol[fv&3]; + queuepoly(V, ct, vid.wallmode == 1 ? shBFloor[ct-6] : shFloor[c->type - 6], col); + if(fjordwalled[fv]) + queuepoly(V, ct, shWall[ct-6], col | 0xFF3F3F); + int siz = int(sqrt(squar(xc-xs)+squar(yc-ys))) / 5; + displaystr(xc, yc, sc, siz, its(fv), 0xFFFFFFFF, 8); + } + } + + else if(c->land == laDesert) + queuepoly(V, ct, (euclid ? shCloudFloor : shDesertFloor)[ct-6], darkena(xcol, 2, 0xFF)); + + else if(c->land == laDryForest) + queuepoly(V, ct, (euclid ? shStarFloor : shDesertFloor)[ct-6], darkena(xcol, 2, 0xFF)); + + else + queuepoly(V, ct, shFloor[ct-6], darkena(xcol, 2, 0xFF)); + // walls + + char xch = winf[c->wall].glyph; + + if(c->wall == waBigStatue) + queuepoly(V, ct, shStatue, + darkena(winf[c->wall].color, 0, 0xFF) + ); + + else if(c->wall == waSulphurC) + queuepoly(V, ct, shGiantStar[ct-6], darkena(xcol, 0, 0xFF)); + + else if(c->wall == waFrozenLake || c->wall == waLake || c->wall == waCamelotMoat || + c->wall == waRoundTable) + ; + + else if(xch == '#') { + if(c->wall == waVinePlant) + xcol = 0x60C000; + queuepoly(V, ct, shWall[ct-6], darkena(xcol, 0, 0xFF)); + } + + else if(xch == '%') + queuepoly(V, ct, shMirror, darkena(xcol, 0, 0xC0)); + + else if(isActiv(c)) { + ld sp = c->tmp > 0 ? ticks / 500. : 0; + queuepoly(V * spin(sp), ct, shStar, darkena(col, 0, 0xF0)); + } + + else if(xch == '+' && c->land == laGraveyard && c->wall != waFloorB && c->wall != waFloorA) + queuepoly(V, ct, shCross, darkena(xcol, 0, 0xFF)); + + else if(xch != '.' && xch != '+' && xch != '>' && xch != ':' && xch != ';' && c->wall != waSulphur) + error = true; + +/* if(c->master->alt) { + int d = celldistAlt(c); + int siz = int(sqrt(squar(xc-xs)+squar(yc-ys))) / 5; + if(d != ALTDIST_UNKNOWN && d != ALTDIST_BOUNDARY) + displaystr(xc, yc, sc, siz, its(d), 0xFFFFFFFF, 8); + } */ + } + else if(!(c->item || c->monst || c->cpdist == 0)) error = true; + + // treasure + + char xch = iinf[c->item].glyph; + hpcshape *xsh = + c->item == itHolyGrail ? &shGrail : + xch == '*' ? &shGem[ct-6] : xch == '%' ? &shDaisy : xch == '$' ? &shStar : xch == ';' ? &shTriangle : + xch == '!' ? &shTriangle : c->item == itBone ? &shNecro : c->item == itStatue ? &shStatue : + xch == '?' ? &shBookCover : + c->item == itKey ? &shKey : NULL; + + if(doHighlight()) { + int k = itemclass(c->item); + if(k == IC_TREASURE) + poly_outline = 0xFFFF00FF; + else if(k == IC_ORB) + poly_outline = 0xFF8000FF; + else + poly_outline = 0xFFFFFFFF; + } + + if(vid.monmode == 0 && c->item) + error = true; + + else if(xsh) + queuepoly(V * spin(ticks / 1500.), ct, *xsh, darkena(icol, 0, 0xF0)); + + else if(xch == 'o') { + if(c->item == itOrbFire) icol = firecolor(100); + queuepoly(V, ct, shDisk, darkena(icol, 0, 0xC0)); + if(c->item == itOrbFire) icol = firecolor(200); + queuepoly(V, ct, shRing, darkena(icol, 0, int(0x80 + 0x70 * sin(ticks / 300.)))); + } + + else if(c->item) error = true; + + if(xsh == &shBookCover) + queuepoly(V * spin(ticks / 1500.), ct, shBook, 0x805020FF); + + // monsters + + if(flashat > 0 && c == flashcell) { + int tim = ticks - flashat; + if(tim > 1000) flashat = 0; + for(int u=0; u<=tim; u++) { + if((u-tim)%50) continue; + if(u < tim-150) continue; + ld rad = u * 3 / 1000.; + rad = rad * (5-rad) / 2; + rad *= hexf; + int col = iinf[itOrbFlash].color; + if(u > 500) col = gradient(col, 0, 500, u, 1100); + for(int a=0; a<84; a++) + drawline(V*ddi(a, rad)*C0, V*ddi(a+1, rad)*C0, col); + } + } + + error |= drawMonster(V, ct, c, col); + +/* if(ch == '.') { + col = darkened(col); + for(int t=0; t= 2) { + displaychr(xc-2, yc, sc, siz, ch, 0); + displaychr(xc+2, yc, sc, siz, ch, 0); + displaychr(xc, yc-2, sc, siz, ch, 0); + displaychr(xc, yc+2, sc, siz, ch, 0); + } + displaychr(xc, yc, sc, siz, ch, col); + } + + if(c == keycell) { + displaychr(xc, yc, sc, 2*vid.fsize, 'X', 0x10101 * int(128 + 100 * sin(ticks / 150.))); + displaystr(xc, yc, sc, vid.fsize, its(keycelldist), 0x10101 * int(128 - 100 * sin(ticks / 150.)), 8); + } + +#if defined(ANDROID) || defined(PANDORA) || defined(IOS) + if(c == lmouseover && (mousepressed || ISANDROID || ISMOBILE)) { + drawCircle(xc, yc, int(sqrt(squar(xc-xs)+squar(yc-ys)) * .8), c->cpdist > 1 ? 0x00FFFF : 0xFF0000); + } +#endif + + if(c == lmouseover && c->land == laGameBoard) { + drawCircle(xc, yc, int(sqrt(squar(xc-xs)+squar(yc-ys)) * .8), 0x00FFFF); + } + + if(joydir >= 0 && c == cwt.c->mov[(joydir+cwt.spin) % cwt.c->type]) + drawCircle(xc, yc, int(sqrt(squar(xc-xs)+squar(yc-ys)) * (.78 - .02 * sin(ticks/199.0))), 0x00FF00); + +#ifndef MOBILE + if(c == lcenterover && !playermoved) + drawCircle(xc, yc, int(sqrt(squar(xc-xs)+squar(yc-ys)) * (.70 - .06 * sin(ticks/200.0))), int(175 + 25 * sin(ticks / 200.0))); +#endif + + if(cmode == emDraw && cwt.c->type == 6 && ct == 6) for(int a=0; arots; a++) { + + transmatrix V2 = V * spin(M_PI + 2*M_PI*a/dsCur->rots); + + if(outofmap(mouseh)) break; + + hyperpoint P2 = V2 * inverse(cwtV) * mouseh; + + int xc, yc, sc; + getcoord(P2, xc, yc, sc); + displaychr(xc, yc, sc, 10, 'x', 0xFF); + + if(crad > 0 && c->cpdist <= 3) { + lalpha = 0x80; + transmatrix movtocc = V2 * inverse(cwtV) * rgpushxto0(ccenter); + for(int d=0; d<84; d++) + drawline(movtocc * ddi(d+1, crad) * C0, movtocc * ddi(d, crad) * C0, 0xC00000); + lalpha = 0xFF; + } + } + + // process mouse + + for(int i=-1; itype; i++) if(i == -1 ? cwt.c == c : cwt.c->mov[i % cwt.c->type] == c) { + int mx = mousex, my = mousey; + if(revcontrol) mx = vid.xcenter*2-mx, my = vid.ycenter*2-my; + + int ndist = (xc-mx) * (xc-mx) + (yc-my) * (yc-my); + if(ndist < mousedist) mousedist = ndist, mousedest = i; + } + + // drawline(V*C0, V*Crad[0], 0xC00000); + if(c->bardir != NODIR && c->bardir != NOBARRIERS) { + drawline(V*C0, V*heptmove[c->bardir]*C0, 0x505050 >> darken); + drawline(V*C0, V*hexmove[c->bardir]*C0, 0x505050 >> darken); + } + + } + } + +string buildCredits(); + +string buildHelpText() { + string h; + h += XLAT("Welcome to HyperRogue"); +#ifdef ANDROID + h += XLAT(" for Android"); +#endif +#ifdef IOS + h += XLAT(" for iOS"); +#endif + h += XLAT("! (version %1)\n\n", VER); + + h += XLAT( +MC "You have been trapped in a strange, non-Euclidean world. Collect as much treasure as possible " +MC "before being caught by monsters. The more treasure you collect, the more " +MC "monsters come to hunt you, as long as you are in the same land type. The " +M "Orbs of Yendor are the ultimate treasure; get at least one of them to win the game!" + ); + h += XLAT(" (press ESC for some hints about it)."); + h += "\n\n"; + + h += XLAT( +MC "You can fight most monsters by moving into their location. " +MC "The monster could also kill you by moving into your location, but the game " +M "automatically cancels all moves which result in that.\n\n" + ); +#ifdef MOBILE + h += XLAT( +MC "Usually, you move by touching somewhere on the map; you can also touch one " +MC "of the four buttons on the map corners to change this (to scroll the map " +MC "or get information about map objects). You can also touch the " +M "numbers displayed to get their meanings.\n" + ); +#else + h += XLAT( +MC "Move with mouse, num pad, qweadzxc, or hjklyubn. Wait by pressing 's' or '.'. Spin the world with arrows, PageUp/Down, and Home/Space. " +MC "To save the game you need an Orb of Safety. Press 'v' for config, ESC for the quest status and menu.\n\n" + ); + h += XLAT( + "You can right click any element to get more information about it.\n\n" + ); +#endif + h += XLAT("See more on the website: ") + + "http//roguetemple.com/z/hyper.php\n\n"; + +#ifdef MOBILE + h += buildCredits(); +#else + h += XLAT("Press 'c' for credits."); +#endif + return h; + } + +string musiclicense; + +string buildCredits() { + string h; + h += XLAT("game design, programming, texts and graphics by Zeno Rogue \n\n"); + if(lang() != 0) + h += XLAT("add credits for your translation here"); +#ifndef NOLICENSE + h += XLAT( +MC "released under GNU General Public License version 2 and thus " +M "comes with absolutely no warranty; see COPYING for details\n\n" + ); +#endif + h += XLAT( +M "special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n", + "Konstantin Stupnik, ortoslon, chrysn, Adam Borowski, Damyan Ivanov, Ryan Farnsley, mcobit, Darren Grey, tricosahedron, Maciej Chojecki, Marek Čtrnáct" + ); +#ifdef EXTRALICENSE + h += EXTRALICENSE; +#endif + if(musiclicense != "") h += musiclicense; + return h; + } + +string generateHelpForItem(eItem it) { + string help = XLAT(iinf[it].help); +#ifdef ANDROID + if(it == itOrbSafety) + help += XLAT("This might be useful for Android devices with limited memory."); + if(it == itGreenStone) + help += XLAT("You can touch the Dead Orb in your inventory to drop it."); +#else + if(it == itOrbSafety) + help += XLAT("Thus, it is potentially useful for extremely long games, which would eat all the memory on your system otherwise.\n"); + if(isRangedOrb(it)) + help += XLAT("You can also scroll to the desired location and then press 't'."); + if(it == itGreenStone) + help += XLAT("You can press 'g' or click them in the list to drop a Dead Orb."); +#endif + return help; + } + +void describeMouseover() { + cell *c = mousing ? mouseover : playermoved ? NULL : centerover; + string out = mouseovers; + if(!c) { } + else if(cmode == emNormal) { + out = XLAT1(linf[c->land].name); + help = XLAT(linf[c->land].help); + + // if(c->land == laIce) out = "Icy Lands (" + fts(60 * (c->heat - .4)) + " C)"; + if(c->land == laIce) out += " (" + fts(60 * (c->heat-.4)) + " °C)"; + if(c->land == laCocytus) out += " (" + fts(60 * (c->heat-.8)) + " °C)"; + if(c->land == laDryForest && c->heat > .5) out += " (" + its(int(c->heat+.1))+"/10)"; + +/* // Hive debug + if(c->land == laHive) { + out += " [" + its(c->tmp) + " H" + its(int(c->heat)); + if(c->tmp >= 0 && c->tmp < size(buginfo) && buginfo[c->tmp].where == c) { + buginfo_t b(buginfo[c->tmp]); + for(int k=0; k<3; k++) out += ":" + its(b.dist[k]); + for(int k=0; k<3; k++) + for(int i=0; itmp) + out += " B"+its(k)+":"+its(i); + } + out += "]"; + } */ + + if(c->wall && !((c->wall == waFloorA || c->wall == waFloorB) && c->item)) { + out += ", "; out += XLAT1(winf[c->wall].name); + if(!((c->wall == waCavefloor || c->wall == waCavewall) && c->land == laFjord)) + help = XLAT(winf[c->wall].help); + } + + if(isActiv(c)) { + if(c->tmp < 0) out += XLAT(" (touch to activate)"); + if(c->tmp == 0) out += XLAT(" (expired)"); + if(c->tmp > 0 && !(c->land == laPower && c->wall == waBonfire)) + out += XLAT(" [%1 turns]", its(c->tmp)); + } + + if(c->monst) {out += ", "; out += XLAT1(minf[c->monst].name); help = XLAT(minf[c->monst].help);} + + if(c->item) { + out += ", "; + out += XLAT1(iinf[c->item].name); + if(!c->monst) help = generateHelpForItem(c->item); + } + + if(!c->cpdist) out += XLAT(", you"); + } + else if(cmode == emVisual1) { + if(getcstat == 'p') { + out = XLAT("0 = Klein model, 1 = Poincaré model"); + if(vid.alpha < -0.5) + out = XLAT("you are looking through it!"); + } + else if(getcstat == 'r') { + out = XLAT("simply resize the window to change resolution"); + } + else if(getcstat == 'f') { + out = XLAT("[+] keep the window size, [-] use the screen resolution"); + } + else if(getcstat == 'a' && vid.aspeed > -4.99) + out = XLAT("+5 = center instantly, -5 = do not center the map"); + else if(getcstat == 'a') + out = XLAT("press Space or Home to center on the PC"); + else if(getcstat == 'w') + out = XLAT("also hold Alt during the game to toggle high contrast"); + else if(getcstat == 'w' || getcstat == 'm') + out = XLAT("You can choose one of the several modes"); + else if(getcstat == 'c') + out = XLAT("The axes help with keyboard movement"); + else if(getcstat == 'g') + out = XLAT("Affects looks and grammar"); +#ifndef MOBILE + else if(getcstat == 's') + out = XLAT("Config file: %1", conffile); +#endif + else out = ""; + } + else if(cmode == emVisual2) { + if(getcstat == 'p') { // stick) { + if(autojoy) + out = XLAT("joystick mode: automatic (release the joystick to move)"); + if(!autojoy) + out = XLAT("joystick mode: manual (press a button to move)"); + } + else if(getcstat == 'e') + out = XLAT("You need special glasses to view the game in 3D"); + else if(getcstat == 'f') + out = XLAT("Reduce the framerate limit to conserve CPU energy"); + } + + mouseovers = out; + #ifndef MOBILE + if(cmode != emPickScores) + displayfr(vid.xres/2, vid.fsize, 2, vid.fsize, out, linf[cwt.c->land].color, 8); + if(mousey < vid.fsize * 3/2) getcstat = SDLK_F1; + #endif + } + +void drawrec(const heptspin& hs, int lev, hstate s, transmatrix V) { + + cell *c = hs.h->c7; + + drawcell(c, V * spin(hs.spin*2*M_PI/7), hs.spin); + + if(lev <= 0) return; + + for(int d=0; d<7; d++) { + int ds = fixrot(hs.spin + d); + // createMov(c, ds); + if(c->mov[ds] && c->spn[ds] == 0) + drawcell(c->mov[ds], V * hexmove[d], 0); + } + + if(lev <= 1) return; + + for(int d=0; d<7; d++) { + hstate s2 = transition(s, d); + if(s2 == hsError) continue; + heptspin hs2 = hsstep(hsspin(hs, d), 0); + drawrec(hs2, lev-2, s2, V * heptmove[d]); + } + + } + +int mindx=-7, mindy=-7, maxdx=7, maxdy=7; + + +void drawEuclidean() { + eucoord px, py; + if(!lcenterover) lcenterover = cwt.c; + printf("centerover = %p player = %p [%d,%d]-[%d,%d]\n", lcenterover, cwt.c, + mindx, mindy, maxdx, maxdy); + decodeMaster(lcenterover->master, px, py); + + int minsx = mindx-1, maxsx=maxdx+1, minsy=mindy-1, maxsy=maxdy+1; + mindx=maxdx=mindy=maxdy=0; + + for(int dx=minsx; dx<=maxsx; dx++) + for(int dy=minsy; dy<=maxsy; dy++) { + eucoord x = dx+px; + eucoord y = dy+py; + cell *c = euclideanAt(x,y); + if(!c) continue; + transmatrix Mat = Id; + Mat[2][2] = 1; + Mat[0][2] += (x + y * .5) * eurad; + double q3 = sqrt(double(3)); + Mat[1][2] += y * q3 /2 * eurad; + while(Mat[0][2] <= -16384 * eurad) Mat[0][2] += 32768 * eurad; + while(Mat[0][2] >= 16384 * eurad) Mat[0][2] -= 32768 * eurad; + while(Mat[1][2] <= -16384 * q3 * eurad) Mat[1][2] += 32768 * q3 * eurad; + while(Mat[1][2] >= 16384 * q3 * eurad) Mat[1][2] -= 32768 * q3 * eurad; + Mat = View * Mat; + + // Mat[0][0] = -1; + // Mat[1][1] = -1; + + // Mat[2][0] = x*x/10; + // Mat[2][1] = y*y/10; + // Mat = Mat * xpush(x-30) * ypush(y-30); + + int cx, cy, shift; + getcoord(Mat * C0, cx, cy, shift); + if(cx >= 0 && cy >= 0 && cx < vid.xres && cy < vid.yres) { + if(dx < mindx) mindx = dx; + if(dy < mindy) mindy = dy; + if(dx > maxdx) maxdx = dx; + if(dy > maxdy) maxdy = dy; + } + + drawcell(c, Mat, 0); + } + } + +void drawthemap() { + + keycell = NULL; + + if(yii < size(yi)) { + if(!yi[yii].found) for(int i=0; icpdist <= sightrange) { + keycell = yi[yii].path[i]; + keycelldist = YDIST - i; + } + } + + #ifndef MOBILE + lmouseover = mouseover; + #endif + mousedist = 1000000; + mousedest = -1; + modist = 1e20; mouseover = NULL; mouseovers = XLAT("Press F1 or right click for help"); + centdist = 1e20; lcenterover = centerover; centerover = NULL; + #ifdef MOBILE + mouseovers = XLAT("No info about this..."); + #endif + if(outofmap(mouseh)) + modist = -5; + playerfound = false; + + if(euclid) + drawEuclidean(); + else + drawrec(viewctr, + (!playermoved) ? sightrange+1 : sightrange + 4, + hsOrigin, View); + } + +void centerpc(ld aspd) { + hyperpoint H = cwtV * C0; + ld R = sqrt(H[0] * H[0] + H[1] * H[1]); + if(R < 1e-9) { + return; + } + + if(euclid) { + // Euclidean + aspd *= (2+3*R*R); + if(aspd > R) aspd = R; + + View[0][2] -= cwtV[0][2] * aspd / R; + View[1][2] -= cwtV[1][2] * aspd / R; + } + + else { + aspd *= (1+R); + + if(R < aspd) { + View = gpushxto0(H) * View; + } + else + View = rspintox(H) * xpush(-aspd) * spintox(H) * View; + } + } + +void drawmovestar() { + + if(!playerfound) return; + + if(vid.axes == 0 || (vid.axes == 1 && mousing)) return; + + hyperpoint H = cwtV * C0; + ld R = sqrt(H[0] * H[0] + H[1] * H[1]); + transmatrix Centered = Id; + + if(euclid) + Centered = eupush(H[0], H[1]); + else if(R > 1e-9) Centered = rgpushxto0(H); + + int starcol = (vid.goteyes? 0xE08060 : 0xC00000); + + if(vid.axes == 3 || (vid.wallmode == 2 && vid.axes == 1)) + queuepoly(Centered, 7, shMovestar, darkena(starcol, 0, 0xFF)); + + else for(int d=0; d<8; d++) { + int col = starcol; +#ifdef PANDORA + if(leftclick && (d == 2 || d == 6 || d == 1 || d == 7)) col >>= 2; + if(rightclick && (d == 2 || d == 6 || d == 3 || d == 5)) col >>= 2; + if(!leftclick && !rightclick && (d&1)) col >>= 2; +#endif +// EUCLIDEAN + if(euclid) + drawline(Centered * C0, Centered * ddi(d * 10.5, 0.5) * C0, col >> darken); + else + drawline(Centered * C0, Centered * spin(M_PI*d/4)* xpush(.5) * C0, col >> darken); + } + } + +void optimizeview() { + + int turn = 0; + ld best = INF; + + transmatrix TB; + + for(int i=-1; i<7; i++) { + + ld trot = -i * M_PI * 2 / 7.0; + transmatrix T = i < 0 ? Id : spin(trot) * xpush(tessf) * spin(M_PI); + hyperpoint H = View * T * C0; + if(H[2] < best) best = H[2], turn = i, TB = T; + } + + if(turn >= 0) { + View = View * TB; + fixmatrix(View); + viewctr = hsspin(viewctr, turn); + viewctr = hsstep(viewctr, 0); + } + } + +int vectodir(const hyperpoint& P) { + hyperpoint H = cwtV * C0; + ld R = sqrt(H[0] * H[0] + H[1] * H[1]); + transmatrix Centered = cwtV; + if(!euclid) + Centered = gpushxto0(H) * Centered; + else if(R > 1e-9) + Centered = eupush(-H[0], -H[1]) * Centered; + int bdir = -1; + ld binv = 99; + for(int i=0; itype; i++) { + ld inv = intval(Centered * spin(-i * 2 * M_PI /cwt.c->type) * xpush(1) * C0, P); + if(inv < binv) binv = inv, bdir = i; + } + // if(euclid) bdir = (bdir + 3) % 6; + return bdir; + } + +void movepckeydir(int d) { + // EUCLIDEAN + if(euclid) + movepcto(vectodir(spin(-d * M_PI/4) * eupush(1, 0) * C0)); + else + movepcto(vectodir(spin(-d * M_PI/4) * xpush(1) * C0)); + } + +void checkjoy() { + ld joyvalue1 = vid.joyvalue * vid.joyvalue; + ld joyvalue2 = vid.joyvalue2 * vid.joyvalue2; + + ld jx = joyx; + ld jy = joyy; + ld sq = jx*jx+jy*jy; + + if(autojoy) { + if(sq < joyvalue1) { if(joydir >= 0) movepcto(joydir); joydir = -1; return; } + if(sq < joyvalue2 && joydir == -1) return; + } + else { + if(sq < joyvalue1) { joydir = -1; return; } + } + + joydir = vectodir(hpxy(jx, jy)); + } + +void checkpanjoy(double t) { + + if(panjoyx * panjoyx + panjoyy * panjoyy < vid.joypanthreshold * vid.joypanthreshold) + return; + + ld jx = panjoyx * t * vid.joypanspeed; + ld jy = panjoyy * t * vid.joypanspeed; + + playermoved = false; + View = gpushxto0(hpxy(jx, jy)) * View; + } + +void calcparam() { + vid.xcenter = vid.xres / 2; + vid.ycenter = vid.yres / 2; + vid.radius = int(vid.scale * vid.ycenter) - (ISANDROID ? 2 : ISIOS ? 40 : 40); + + if(vid.xres < vid.yres) { + vid.radius = int(vid.scale * vid.xcenter) - (ISIOS ? 10 : 2); + vid.ycenter = vid.yres - vid.radius - vid.fsize - (ISIOS ? 10 : 0); + } + + vid.beta = 1 + vid.alpha + vid.eye; + vid.alphax = vid.alpha + vid.eye; + vid.goteyes = vid.eye > 0.001 || vid.eye < -0.001; + } + +#ifndef MOBILE +void displayStat(int y, const string& name, const string& val, char mkey) { + + int dy = vid.fsize * y + vid.yres/4; + int dx = vid.xres/2 - 100; + + bool xthis = (mousey >= dy-vid.fsize/2 && mousey <= dy + vid.fsize/2); + int xcol = 0x808080; + + if(xthis) { + getcstat = mkey; getcshift = 0; + int mx = mousex - dx; + if(mx >= 0 && mx <= 100) { + if(mx < 20) getcshift = -1 , xcol = 0xFF0000; + else if(mx < 40) getcshift = -0.1 , xcol = 0x0000FF; + else if(mx < 50) getcshift = -0.01, xcol = 0x00FF00; + if(mx > 80) getcshift = +1 , xcol = 0xFF0000; + else if(mx > 60) getcshift = +0.1 , xcol = 0x0000FF; + else if(mx > 50) getcshift = +0.01, xcol = 0x00FF00; + } + } + + if(val != "") { + displaystr(dx, dy, 0, vid.fsize, val, xthis ? 0xFFFF00 : 0x808080, 16); + displaystr(dx+25, dy, 0, vid.fsize, "-", xthis && getcshift < 0 ? xcol : 0x808080, 8); + displaystr(dx+75, dy, 0, vid.fsize, "+", xthis && getcshift > 0 ? xcol : 0x808080, 8); + } + + displaystr(dx+100, dy, 0, vid.fsize, s0 + mkey, xthis ? 0xFFFF00 : 0xC0F0C0, 0); + + displaystr(dx+125, dy, 0, vid.fsize, name, xthis ? 0xFFFF00 : 0x808080, 0); + } + +void displayStatHelp(int y, string name) { + + int dy = vid.fsize * y + vid.yres/4; + int dx = vid.xres/2 - 100; + + displaystr(dx+100, dy, 0, vid.fsize, name, 0xC0C0C0, 0); + } + +void displayButton(int x, int y, const string& name, int key, int align, int rad = 0) { + if(displayfr(x, y, rad, vid.fsize, name, 0x808080, align)) { + displayfr(x, y, rad, vid.fsize, name, 0xFFFF00, align); + getcstat = key; + } + } + +void quitOrAgain() { + int y = vid.yres * (618) / 1000; + displayButton(vid.xres/2, y + vid.fsize*1/2, + (items[itOrbSafety] && havesave) ? + XLAT("Press Enter or F10 to save") : + XLAT("Press Enter or F10 to quit"), + SDLK_RETURN, 8, 2); + displayButton(vid.xres/2, y + vid.fsize*2, XLAT("or 'r' or F5 to restart"), 'r', 8, 2); + displayButton(vid.xres/2, y + vid.fsize*7/2, XLAT("or 't' to see the top scores"), 't', 8, 2); + if(canmove) displayButton(vid.xres/2, y + vid.fsize*10/2, XLAT("or another key to continue"), ' ', 8, 2); + else displayButton(vid.xres/2, y + vid.fsize*10/2, XLAT("or ESC to see how it ended"), ' ', 8, 2); + } +#endif + +int calcfps() { + #define CFPS 30 + static int last[CFPS], lidx = 0; + int ct = ticks; + int ret = ct - last[lidx]; + last[lidx] = ct; + lidx++; lidx %= CFPS; + if(ret == 0) return 0; + return (1000 * CFPS) / ret; + } + +int msgscroll = 0; + +string timeline() { + int timespent = savetime + (timerstopped ? 0 : (time(NULL) - timerstart)); + char buf[20]; + sprintf(buf, "%d:%02d", timespent/60, timespent % 60); + return XLAT("%1 turns (%2)", its(turncount), buf); + } + +void showGameover() { + int y = vid.yres * (1000-618) / 1000 - vid.fsize * 7/2; + displayfr(vid.xres/2, y, 4, vid.fsize*2, + cheater ? XLAT("It is a shame to cheat!") : + showoff ? XLAT("Showoff mode") : + canmove ? XLAT("Quest status") : + XLAT("GAME OVER"), 0xC00000, 8 + ); + displayfr(vid.xres/2, y + vid.fsize*2, 2, vid.fsize, XLAT("Your score: %1", its(gold())), 0xD0D0D0, 8); + displayfr(vid.xres/2, y + vid.fsize*3, 2, vid.fsize, XLAT("Enemies killed: %1", its(tkills())), 0xD0D0D0, 8); + + if(!timerstopped && !canmove) { + savetime += time(NULL) - timerstart; + timerstopped = true; + } + if(canmove && !timerstart) + timerstart = time(NULL); + + if(items[itOrbYendor]) { + displayfr(vid.xres/2, y + vid.fsize*4, 2, vid.fsize, XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), 0xFF00FF, 8); + displayfr(vid.xres/2, y + vid.fsize*5, 2, vid.fsize, XLAT("CONGRATULATIONS!"), 0xFFFF00, 8); + } + else { + if(gold() < 30) + displayfr(vid.xres/2, y+vid.fsize*5, 2, vid.fsize, XLAT("Collect 30 $$$ to access more worlds"), 0xC0C0C0, 8); + else if(gold() < 60) + displayfr(vid.xres/2, y+vid.fsize*5, 2, vid.fsize, XLAT("Collect 60 $$$ to access even more lands"), 0xC0C0C0, 8); + else if(!hellUnlocked()) + displayfr(vid.xres/2, y+vid.fsize*5, 2, vid.fsize, XLAT("Collect at least 10 treasures in each of 9 types to access Hell"), 0xC0C0C0, 8); + else if(items[itHell] < 10) + displayfr(vid.xres/2, y+vid.fsize*5, 2, vid.fsize, XLAT("Collect at least 10 Demon Daisies to find the Orbs of Yendor"), 0xC0C0C0, 8); + else if(size(yi) == 0) + displayfr(vid.xres/2, y+vid.fsize*5, 2, vid.fsize, XLAT("Look for the Orbs of Yendor in Hell or in the Crossroads!"), 0xC0C0C0, 8); + else + displayfr(vid.xres/2, y+vid.fsize*5, 2, vid.fsize, XLAT("Unlock the Orb of Yendor!"), 0xC0C0C0, 8); + } + if(tkills() < 100) + displayfr(vid.xres/2, y+vid.fsize*6, 2, vid.fsize, XLAT("Defeat 100 enemies to access the Graveyard"), 0xC0C0C0, 8); + else if(hellUnlocked()) { + #define NUMSEQ 19 + eLand seq[NUMSEQ] = { + laHell, laCocytus, laGraveyard, + laWineyard, laFjord, laHive, laDeadCaves, laPower, + laRlyeh, laTemple, laDryForest, laIce, laCaves, + laJungle, laDesert, laAlchemist, laMotion, laMirror, laCrossroads + }; + bool b = true; + for(int i=0; i=0) { + msginfo m; + m.spamtype = 0; + m.flashout = true; + m.stamp = ticks-128*vid.flashtime-128*(gls-i); + m.msg = gamelog[i]; + mnum++, + msgs.push_back(m); + } + + if(mnum) + displayfr(vid.xres/2, vid.yres-vid.fsize*(mnum+1), 2, vid.fsize/2, XLAT("last messages:"), 0xC0C0C0, 8); + + #ifndef MOBILE + quitOrAgain(); + #endif + } + +void displayabutton(int px, int py, string s, int col) { + // TMP + int siz = vid.yres > vid.xres ? vid.fsize*2 : vid.fsize * 3/2; + int x = vid.xcenter + px * (vid.radius); + int y = vid.ycenter + py * (vid.radius - siz/2); + if(gtouched && !mouseover + && abs(mousex - vid.xcenter) < vid.radius + && abs(mousey - vid.ycenter) < vid.radius + && hypot(mousex-vid.xcenter, mousey-vid.ycenter) > vid.radius + && px == (mousex > vid.xcenter ? 1 : -1) + && py == (mousey > vid.ycenter ? 1 : -1) + ) col = 0xFF0000; + displayfr(x, y, 0, siz, s, col, 8+8*px); + } + +vector scores; + +int scoresort = 2; +int scoredisplay = 1; +int scorefrom = 0; +bool scorerev = false; + +bool scorecompare(const score& s1, const score &s2) { + return s1.box[scoresort] > s2.box[scoresort]; + } + +bool fakescore() { + return fakebox[scoredisplay]; + } + +string displayfor(score* S) { + // printf("S=%p, scoredisplay = %d\n", S, scoredisplay); + if(S == NULL) { + return XLATN(boxname[scoredisplay]); + } + if(scoredisplay == 0) { + char buf[10]; + snprintf(buf, 10, "%d:%02d", S->box[0]/60, S->box[0]%60); + return buf; + } + if(scoredisplay == 1) { + time_t tim = S->box[1]; + char buf[128]; strftime(buf, 128, "%c", localtime(&tim)); + return buf; + } + return its(S->box[scoredisplay]); + } + +#ifndef ANDROID +void loadScores() { + scores.clear(); + FILE *f = fopen(scorefile, "rt"); + if(!f) { + printf("Could not open the score file '%s'!\n", scorefile); + addMessage(s0 + "Could not open the score file: " + scorefile); + return; + } + while(!feof(f)) { + char buf[120]; + if(fgets(buf, 120, f) == NULL) break; + if(buf[0] == 'H' && buf[1] == 'y') { + score sc; bool ok = true; + if(fscanf(f, "%s", buf) <= 0) break; sc.ver = buf; + + for(int i=0; i= "4.4") { + sc.box[0] = sc.box[65]; + // the first executable on Steam included a corruption + if(sc.box[65] > 1420000000 && sc.box[65] < 1430000000) { + sc.box[0] = sc.box[65] - sc.box[1]; + sc.box[65] = sc.box[0]; + } + // do not include saves + if(sc.box[65 + 4 + itOrbSafety - itOrbLightning]) ok = false; + } + else + sc.box[0] = sc.box[1] - sc.box[0]; // could not save then + if(ok && boxid > 20) scores.push_back(sc); + } + } + fclose(f); + addMessage(its(size(scores))+" games have been recorded in "+scorefile); + cmode = emScores; + scoresort = 2; reverse(scores.begin(), scores.end()); + scorefrom = 0; + stable_sort(scores.begin(), scores.end(), scorecompare); + } + +bool notgl = false; + +void showPickScores() { + + int d = scoredisplay; + + vector > v; + for(int i=0; i= size(scores)) break; + score& S(scores[id]); + char buf[16]; + + sprintf(buf, "%d", id+1); + displaystr(bx*4, y, 0, vid.fsize, buf, 0xC0C0C0, 16); + + sprintf(buf, "%d", S.box[2]); + displaystr(bx*8, y, 0, vid.fsize, buf, 0xC0C0C0, 16); + + sprintf(buf, "%d", S.box[3]); + displaystr(bx*12, y, 0, vid.fsize, buf, 0xC0C0C0, 16); + + sprintf(buf, "%d:%02d", S.box[0]/60, S.box[0] % 60); + displaystr(bx*18, y, 0, vid.fsize, buf, 0xC0C0C0, 16); + + displaystr(bx*22, y, 0, vid.fsize, S.ver, 0xC0C0C0, 16); + + displaystr(bx*23, y, 0, vid.fsize, displayfor(&S), 0xC0C0C0, 0); + + y += vid.fsize*5/4; id++; + } + +#ifdef IOS + displayabutton(-1, +1, XLAT("SORT"), BTON); + displayabutton(+1, +1, XLAT("PLAY"), BTON); +#endif + } + +void sortScores() { + if(scorerev) reverse(scores.begin(), scores.end()); + else { + scorerev = true; + scoresort = scoredisplay; + stable_sort(scores.begin(), scores.end(), scorecompare); + } + } + +void shiftScoreDisplay(int delta) { + scoredisplay = (scoredisplay + POSSCORE + delta) % POSSCORE, scorerev = false; + if(fakescore()) shiftScoreDisplay(delta); + } +#endif + +#ifndef MOBILE +void handleScoreKeys(int sym, SDL_Event& ev) { + if(sym == SDLK_LEFT || sym == SDLK_KP4 || sym == 'h' || sym == 'a') + shiftScoreDisplay(-1); + else if(sym == SDLK_RIGHT || sym == SDLK_KP6 || sym == 'l' || sym == 'd') + shiftScoreDisplay(1); + else if(sym == 't') cmode = emPickScores; + else if(sym == SDLK_UP || sym == 'k' || sym == 'w') + scorefrom -= 5; + else if(sym == SDLK_DOWN || sym == 'j' || sym == 'x') + scorefrom += 5; + else if(sym == 's') sortScores(); + else if(sym != 0 || ev.type == SDL_MOUSEBUTTONDOWN) cmode = emNormal; + } + +void handlePickScoreKeys(int uni, SDL_Event& ev) { + if(uni != 0) { + int k = uni - '!'; + if(k >= 0 && k < POSSCORE) scoredisplay = k; + cmode = emScores; + scorerev = false; + } + } + +#endif + +string ONOFF(bool b) { + return XLAT(b ? "ON" : "OFF"); + } + +void drawStats() { + + DEB("stats"); + +#ifdef IOS + if(cmode != emNormal && cmode != emQuit) + return; +#endif + + int vx, vy; + + if(vid.xres < vid.yres) { + vx = vid.fsize * 3; + vy = vid.fsize * 2; + } + else { + vx = vid.xres - vid.fsize * 3; + vy = vid.fsize; + } + + #define ADV(z) \ + if(vid.xres < vid.yres) { \ + vx += vid.fsize*4; \ + if(vx > vid.xres - vid.fsize*2) vx = vid.fsize * 3, vy += vid.fsize; \ + } \ + else { \ + vy += vid.fsize * z/2; \ + if(vy > vid.yres) vx += (vx > vid.xres/2 ? -5:5) * vid.fsize, vy = vid.fsize * 5/2; \ + } + + DEB("$$$"); + if(displaynum(vx, vy, 0, vid.fsize, 0xFFFFFF, gold(), "$$$")) { + mouseovers = XLAT("Your total wealth"), + help = XLAT( +MC "The total value of the treasure you have collected.\n\n" +MC "Every world type contains a specific type of treasure, worth 1 $$$; " +MC "your goal is to collect as much treasure as possible, but every treasure you find " +MC "causes more enemies to hunt you in its native land.\n\n" +M "Orbs of Yendor are worth 50 $$$ each.\n\n" + ); + } + + DEB("$$$Z"); + ADV(3); + + int oldz = 0; + + for(int z=0; z<3; z++) for(int i=0; i= 3) { + int kvx, kvy; + if(vid.xres >= vid.yres) + kvx = vid.fsize * 8, kvy = vid.fsize; + else { ADV(2); kvx=vx, kvy=vy; } + if(displaynum(kvx, kvy, 0, vid.fsize, 0xFFFFFF, tkills(), "XX")) + mouseovers = XLAT("Your total kills"), + help = XLAT( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count."); + } + + ADV(3); + + int s = vid.fsize; + if(vid.xres >= vid.yres) + vid.fsize = vid.fsize - vid.killreduction; + + for(int i=1; i vid.fsize * 3 && vid.xres >= vid.yres && vid.xres < vid.yres * 5/3) + vid.killreduction++; + + DEB("stats OK"); + achievement_display(); + } + +void drawscreen() { + +#ifdef GL + if(vid.usingGL) setGLProjection(); +#endif + + calcparam(); + if(cmode != emHelp) help = "@"; + + #ifndef MOBILE + // SDL_LockSurface(s); + // unsigned char *b = (unsigned char*) s->pixels; + // int n = vid.xres * vid.yres * 4; + // while(n) *b >>= 1, b++, n--; + // memset(s->pixels, 0, vid.xres * vid.yres * 4); + if(!vid.usingGL) SDL_FillRect(s, NULL, 0); + #endif + + if(!canmove) darken = 1; + if(cmode != emNormal && cmode != emDraw && cmode != emCustomizeChar) darken = 2; + if(cmode == emQuit && !canmove) darken = 0; + + if(!vid.goteyes && !euclid) + drawCircle(vid.xcenter, vid.ycenter, vid.radius, 0xFF); + + if(vid.wallmode < 2 && !euclid && !(vid.boardmode != 'h' && cwt.c->land == laGameBoard)) { + int ls = size(lines); + if(ISMOBILE) ls /= 10; + for(int t=0; t> darken); + } + + drawqueue(); + ptds.clear(); + + DEB("dmap"); + + drawthemap(); + + DEB("mstar"); + #ifndef MOBILE + if(cmode == emNormal) drawmovestar(); + #endif + + if(cmode == emDraw) { + lalpha = 0x20; + for(int d=0; d<84; d++) + drawline(C0, spin(M_PI*d/42)* xpush(crossf) * C0, 0xC0C0C0); + for(int d=0; d<84; d++) for(int u=2; u<=20; u++) + drawline(spin(M_PI*d/42)* xpush(crossf*u/20) * C0, spin(M_PI*(d+1)/42)* xpush(crossf*u/20) * C0, 0xC0C0C0); + + lalpha = 0x80; + if(crad > 0) { + transmatrix movtocc = rgpushxto0(ccenter); + for(int d=0; d<84; d++) + drawline(movtocc * ddi(d+1, crad) * C0, movtocc * ddi(d, crad) * C0, 0x00C000); + } + // spin(M_PI*(d+1)/42) * xpush(crad) * spin(-M_PI*(d+1)/42) * ccenter, spin(M_PI*d/42) * xpush(crad) * spin(-M_PI*d/42) * ccenter, 0xC0C0C0); + lalpha = 0xFF; + } + + getcstat = 0; + + if(cmode == emNormal || cmode == emQuit) drawStats(); + + #ifdef MOBILE + + if(cmode == emNormal) { + displayabutton(-1, -1, XLAT("MOVE"), andmode == 0 ? BTON : BTOFF); + displayabutton(+1, -1, XLAT(andmode == 1 ? "BACK" : "DRAG"), andmode == 1 ? BTON : BTOFF); + displayabutton(-1, +1, XLAT("INFO"), andmode == 2 ? BTON : BTOFF); + displayabutton(+1, +1, XLAT(ISIOS ? "MENU" : andmode == 3 ? "QUEST" : "HELP"), + andmode == 3 ? (ISIOS ? BTON : 0xFF00FF) : BTOFF); + } + + if(cmode == emQuit) { + displayabutton(-1, +1, XLAT("NEW"), BTON); + displayabutton(+1, +1, XLAT(canmove ? "PLAY" : ISIOS ? " " : "SHARE"), BTON); + } + #endif + + if(cmode == emDraw) { + mouseovers = + floordraw ? (cwt.c->type == 6 ? "hex floor" : "hepta floor") : "character"; + + mouseovers = + XLAT("Drawing %1 (layer %2), F1 for help", XLAT(mouseovers), its(dslayer)); + } + + // displaynum(vx,100, 0, 24, 0xc0c0c0, celldist(cwt.c), ":"); + + darken = 0; + drawmessages(); + + DEB("msgs1"); + if(cmode == emNormal) { + #ifdef MOBILE + if(!canmove) cmode = emQuit; + #endif + if(!canmove) showGameover(); + #ifndef MOBILE +// if(!canmove) +// displayButton(vid.xres-8, vid.yres-vid.fsize*2, XLAT("ESC for menu/quest"), SDLK_ESCAPE, 16); + #endif + } + + #ifndef ANDROID + if(cmode == emScores) + showScores(); + + if(cmode == emPickScores) + showPickScores(); + #endif + + #ifndef MOBILE + if(cmode == emChangeMode) { + displayStat(2, XLAT("vector graphics editor"), "", 'g'); + displayStat(3, XLAT("Euclidean mode"), "", 'e'); + displayStat(4, XLAT("cheat mode"), "", 'c'); + displayStat(6, XLAT("heptagonal game board"), "", '7'); + displayStat(7, XLAT("triangular game board"), "", '3'); + displayStat(8, XLAT("HyperRogue game board"), "", 'h'); + displayStat(9, XLAT("Periodic Editor"), "", 'f'); + + displayStat(18, XLAT("first page [Space]"), "", ' '); + displayStat(19, XLAT("exit configuration"), "", 'v'); + } + + if(cmode == emCustomizeChar) { + displayStatHelp(0, XLAT("Customize character")); + + displayStat(2, XLAT("gender"), XLAT(vid.female ? "female" : "male"), 'g'); + displayStat(3, XLAT("skin color"), "?", 's'); + displayStat(4, XLAT("weapon color"), "?", 'w'); + displayStat(5, XLAT("hair color"), "?", 'h'); + if(vid.female) + displayStat(6, XLAT("dress color"), "?", 'd'); + + displayStatHelp(16, XLAT("Shift=random, Ctrl=mix")); + + displayStat(19, XLAT("exit configuration"), "", 'v'); + } + + if(cmode == emPickEuclidean) { + int s = vid.fsize; + vid.fsize = vid.fsize * 4/5; + displayStatHelp(0, XLAT("Euclidean mode")); + int lt = landtypes; + landvisited[laCrossroads] = true; + landvisited[laIce] = true; + landvisited[laMirror] = true; + // for(int i=2; i= 500) siz = (siz * 9)/10; + else if(ISIOS) siz = (siz * 3+1)/2; + else if(size(help) >= 500) siz = siz * 2/3; + + int vy = vid.fsize * 4; + + int xs = vid.xres * 618/1000; + int xo = vid.xres * 186/1000; + + for(int i=0; i<=size(help); i++) { + int ls = 0; + int prev = last; + if(help[i] == ' ') lastspace = i; + if(textwidth(siz, help.substr(last, i-last)) > xs) { + if(lastspace == last) ls = i-1, last = i-1; + else ls = lastspace, last = ls+1; + } + if(help[i] == 10 || i == size(help)) ls = i, last = i+1; + if(ls) { + displayfr(xo, vy, 2, siz, help.substr(prev, ls-prev), 0xC0C0C0, 0); + if(ls == prev) vy += siz/2; + else vy += siz; + lastspace = last; + } + } + } +#endif + +#ifndef MOBILE + if(mouseover && targetclick) { + eItem i = targetRangedOrb(mouseover, roCheck); + if(i) + displaychr(mousex, mousey, 0, vid.fsize, '@', iinf[i].color); + } +#endif + + #ifndef MOBILE + DEB("msgs3"); + // SDL_UnlockSurface(s); + +#ifdef GL + if(vid.usingGL) SDL_GL_SwapBuffers(); else +#endif + SDL_UpdateRect(s, 0, 0, vid.xres, vid.yres); + + #endif + + if(playermoved && vid.aspeed > 4.99) { + centerpc(1000); + playermoved = false; + return; + } + + } + +#ifndef MOBILE +bool setfsize = false; + +void setvideomode() { + + if(!vid.full) { + if(vid.xres > vid.xscr) vid.xres = vid.xscr * 9/10, setfsize = true; + if(vid.yres > vid.yscr) vid.yres = vid.yscr * 9/10, setfsize = true; + } + + if(setfsize) vid.fsize = min(vid.yres / 32, vid.xres / 48), setfsize = false; + + int flags = 0; + +#ifdef GL + if(vid.usingGL) { + flags = SDL_OPENGL | SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER; + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); + } +#endif + + int sizeflag = (vid.full ? SDL_FULLSCREEN : SDL_RESIZABLE); + + s= SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | sizeflag); + + if(vid.full && !s) { + vid.xres = vid.xscr; + vid.yres = vid.yscr; + vid.fsize = min(vid.yres / 32, vid.xres / 48); + s = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | SDL_FULLSCREEN); + } + + if(!s) { + addMessage("Failed to set the graphical mode: "+its(vid.xres)+"x"+its(vid.yres)+(vid.full ? " fullscreen" : " windowed")); + vid.xres = 640; + vid.yres = 480; + s = SDL_SetVideoMode(vid.xres, vid.yres, 32, flags | SDL_RESIZABLE); + } + +#ifdef GL + glViewport(0, 0, vid.xres, vid.yres); + resetGL(); +#endif + } +#endif + +void restartGraph() { + if(euclid) { + centerover = euclideanAtCreate(0,0); + printf("centerover = %p\n", centerover); + } + else { + viewctr.h = &origin; + viewctr.spin = 0; + } + View = Id; + webdisplay = 0; + } + +#ifndef ANDROID +void saveConfig() { + FILE *f = fopen(conffile, "wt"); + if(!f) { + addMessage(s0 + "Could not open the config file: " + conffile); + return; + } + fprintf(f, "%d %d %d %d\n", vid.xres, vid.yres, vid.full, vid.fsize); + fprintf(f, "%f %f %f %f\n", float(vid.scale), float(vid.eye), float(vid.alpha), float(vid.aspeed)); + fprintf(f, "%d %d %d %d %d %d %d\n", vid.wallmode, vid.monmode, vid.axes, audiovolume, vid.framelimit, vid.usingGL, vid.usingAA); + fprintf(f, "%d %d %d %f %d %d\n", vid.joyvalue, vid.joyvalue2, vid.joypanthreshold, vid.joypanspeed, autojoy, vid.flashtime); + fprintf(f, "%d %d %08x %08x %08x %08x\n", + vid.female?1:0, vid.language, vid.skincolor, vid.haircolor, vid.swordcolor, vid.dresscolor); + + fprintf(f, "%d %d\n", vid.darkhepta, vid.shifttarget); + + fprintf(f, "\n\nThis is a configuration file for HyperRogue (version "VER")\n"); + fprintf(f, "\n\nThe numbers are:\n"); + fprintf(f, "screen width & height, fullscreen mode (0=windowed, 1=fullscreen), font size\n"); + fprintf(f, "scale, eye distance, parameter, animation speed\n"); + fprintf(f, "wallmode, monster mode, cross mode, audiovolume, framerate limit, usingGL, usingAA\n"); + fprintf(f, "calibrate first joystick (threshold A, threshold B), calibrate second joystick (pan threshold, pan speed), joy mode\n"); + fprintf(f, "gender (1=female), language, skin color, hair color, sword color, dress color\n"); + fprintf(f, "darken hepta, shift target\n"); + + fclose(f); + addMessage(s0 + "Configuration saved to: " + conffile); + } + +void loadConfig() { + vid.xres = 9999; vid.yres = 9999; vid.framelimit = 300; + FILE *f = fopen(conffile, "rt"); + if(f) { + int fs, gl=1, aa=1, bb=1; + int err; + err=fscanf(f, "%d%d%d%d", &vid.xres, &vid.yres, &fs, &vid.fsize); + vid.full = fs; + float a, b, c, d; + err=fscanf(f, "%f%f%f%f\n", &a, &b, &c, &d); + if(err == 4) { + vid.scale = a; vid.eye = b; vid.alpha = c; vid.aspeed = d; + } + err=fscanf(f, "%d%d%d%d%d%d%d", &vid.wallmode, &vid.monmode, &vid.axes, &audiovolume, &vid.framelimit, &gl, &aa); + vid.usingGL = gl; vid.usingAA = aa; + err=fscanf(f, "%d%d%d%f%d%d", &vid.joyvalue, &vid.joyvalue2, &vid.joypanthreshold, &vid.joypanspeed, &aa, &vid.flashtime); + autojoy = aa; aa = 0; + err=fscanf(f, "%d%d%x%x%x%x", &aa, &vid.language, &vid.skincolor, &vid.haircolor, &vid.swordcolor, &vid.dresscolor); + vid.female = aa; + aa=0; bb=0; + err=fscanf(f, "%d%d", &aa, &bb); + vid.darkhepta = aa; vid.shifttarget = bb; + + fclose(f); + printf("Loaded configuration: %s\n", conffile); + } + +#ifndef MOBILE + if(clWidth) vid.xres = clWidth; + if(clHeight) vid.yres = clHeight; + if(clFont) vid.fsize = clFont; + + for(int k=0; k 0) { + for(int i=0; buf[i]; i++) if(buf[i] == 10 || buf[i] == 13) buf[i] = 0; + if(buf[0] == '[' && buf[3] == ']') { + int id = (buf[1] - '0') * 10 + buf[2] - '0'; + if(id >= 0 && id < landtypes) { + if(buf[5] == '*' && buf[6] == '/') musfname[id] = dir2 + (buf+7); + else musfname[id] = buf+5; + } + else { + fprintf(stderr, "warning: bad soundtrack id, use the following format:\n"); + fprintf(stderr, "[##] */filename\n"); + fprintf(stderr, "where ## are two digits, and */ is optional and replaced by path to the music\n"); + fprintf(stderr, "alternatively LAST = reuse the last track instead of having a special one"); + } + // printf("[%2d] %s\n", id, buf); + } + else if(buf[0] == '#') { + } + else { + musiclicense += buf; + musiclicense += "\n"; + } + } + fclose(f); + return true; + } + return false; + } +#endif + +void initgraph() { + + vid.usingGL = true; + vid.usingAA = true; + vid.flashtime = 8; + vid.scale = 1; + vid.alpha = 1; + vid.aspeed = 0; + vid.eye = 0; + vid.full = false; + vid.quick = true; +#ifdef ANDROID + vid.wallmode = 2; +#else + vid.wallmode = 3; +#endif + + vid.joyvalue = 4800; + vid.joyvalue2 = 5600; + vid.joypanthreshold = 2500; + vid.joypanspeed = 0.0001; + + vid.framelimit = 75; + vid.monmode = 2; + vid.axes = 1; + + vid.skincolor = 0xD0D0D0FF; + vid.haircolor = 0x686868FF; + vid.dresscolor= 0xC00000FF; + vid.swordcolor= 0xD0D0D0FF; + + vid.killreduction = 0; + + vid.female = false; + vid.language = -1; + vid.boardmode = 'h'; + + joyx = joyy = 0; joydir = -1; + + restartGraph(); + + initgeo(); + + buildpolys(); + for(int i=0; i<8; i++) + dsUser[i][0].rots = 6, + dsUser[i][1].rots = 7, + dsUser[i][2].rots = 1, dsUser[i][2].sym = true; + + for(int i=0; i<8; i++) for(int k=0; k<3; k++) + dsUser[i][k].shift = C0, dsUser[i][k].spin = Cx1; + + #ifndef MOBILE + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) == -1) + { + printf("Failed to initialize video.\n"); + exit(2); + } + const SDL_VideoInfo *inf = SDL_GetVideoInfo(); + vid.xscr = vid.xres = inf->current_w; + vid.yscr = vid.yres = inf->current_h; + + SDL_WM_SetCaption("HyperRogue " VER, "HyperRogue "VER); + + loadConfig(); + + setvideomode(); + if(!s) { + printf("Failed to initialize graphics.\n"); + exit(2); + } + + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + SDL_EnableUNICODE(1); + + if(TTF_Init() != 0) { + printf("Failed to initialize TTF.\n"); + exit(2); + } + + if(SDL_NumJoysticks()) stick = SDL_JoystickOpen(0); + if(SDL_NumJoysticks() >= 2) panstick = SDL_JoystickOpen(1); + + #ifdef AUDIO + + audio = + loadMusicInfo(musicfile) + || loadMusicInfo("./hyperrogue-music.txt") + || loadMusicInfo("music/hyperrogue-music.txt") +#ifdef FHS + || loadMusicInfo("/usr/share/hyperrogue/hyperrogue-music.txt") + || loadMusicInfo(s0 + getenv("HOME") + "/.hyperrogue-music.txt") +#endif + ; + + if(audio) { + if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096) != 0) { + fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); + audio = false; + } + else { + audio = true; + Mix_AllocateChannels(4); + } + } + #endif + + #endif + } + +int frames; +bool outoffocus = false; + +#ifdef AUDIO + +bool loaded[landtypes]; +Mix_Music* music[landtypes]; +int musicpos[landtypes]; +int musstart; +int musfadeval = 2000; + +eLand cid = laNone; + +void handlemusic() { + if(audio && audiovolume) { + eLand id = cwt.c->land; + if(outoffocus) id = eLand(0); + if(musfname[id] == "LAST") id = cid; + if(!loaded[id]) { + loaded[id] = true; + // printf("loading (%d)> %s\n", id, musfname[id].c_str()); + if(musfname[id] != "") { + music[id] = Mix_LoadMUS(musfname[id].c_str()); + if(!music[id]) { + printf("Mix_LoadMUS: %s\n", Mix_GetError()); + } + } + } + if(cid != id && !musfadeval) { + musicpos[cid] = SDL_GetTicks() - musstart; + musfadeval = musicpos[id] ? 500 : 2000; + Mix_FadeOutMusic(musfadeval); + // printf("fadeout %d, pos %d\n", musfadeval, musicpos[cid]); + } + if(music[id] && !Mix_PlayingMusic()) { + cid = id; + Mix_VolumeMusic(audiovolume); + Mix_FadeInMusicPos(music[id], -1, musfadeval, musicpos[id] / 1000.0); + // printf("fadein %d, pos %d\n", musfadeval, musicpos[cid]); + musstart = SDL_GetTicks() - musicpos[id]; + musicpos[id] = 0; + musfadeval = 0; + } + } + } + + +void resetmusic() { + if(audio && audiovolume) { + Mix_FadeOutMusic(3000); + cid = laNone; + for(int i=0; i> 8, cs[rand() % q] >> 8, 0, rand() % 101, 100) << 8) + 0xFF; + else + c = cs[(id+1) % q]; + } + +const char* drawhelp = + "In this mode you can draw your own player character and floors. " + "Mostly for the development purposes, but you can have fun too.\n\n" + "f - floor, p - player (repeat 'p' for layers)\n\n" + "n - new shape, u - copy the 'player body' shape\n\n" + "1-9 - rotational symmetries, 0 - toggle axial symmetry\n\n" + "point with mouse and: a - add point, m - move nearest point, d - delete nearest point, c - nearest point again, b - add after nearest\n\n" + "s - save in C++ format (but cannot be loaded yet without editing source)\n\n" + "z - zoom, o - Poincaré model\n"; + +#ifndef MOBILE + +// Warning: a very long function! todo: refactor + +void loadShape(hpcshape& sh, int d, int layer) { + dsCur = &(dsUser[layer][2]); + dsCur->list.clear(); + dsCur->sym = d==2; + for(int i=sh.s; i < sh.s + (sh.e-sh.s)/d; i++) + dsCur->list.push_back(hpc[i]); + } + +void mainloop() { + int lastt = 0; + while(true) { + + #ifndef GFX + #ifndef GL + vid.wallmode = 0; + vid.monmode = 0; + #endif + #endif + + DEB("screen"); + optimizeview(); + ticks = SDL_GetTicks(); + + dslayer %= 8; + dsCur = &(dsUser[dslayer][floordraw ? cwt.c->type-6 : 2]); + + int cframelimit = vid.framelimit; + if((cmode == emVisual1 || cmode == emVisual2 || cmode == emHelp || cmode == emQuit) && cframelimit > 15) + cframelimit = 15; + if(outoffocus && cframelimit > 10) cframelimit = 10; + + int timetowait = lastt + 1000 / cframelimit - ticks; + if(timetowait > 0) + SDL_Delay(timetowait); + else { + if(playermoved && vid.aspeed > -4.99 && !outoffocus) + centerpc((ticks - lastt) / 1000.0 * exp(vid.aspeed)); + if(panstick || panjoyx || panjoyy) + checkpanjoy((ticks - lastt) / 1000.0); + lastt = ticks; + frames++; + if(!outoffocus) drawscreen(); + } + + Uint8 *keystate = SDL_GetKeyState(NULL); + rightclick = keystate[SDLK_RCTRL]; + leftclick = keystate[SDLK_RSHIFT]; + hiliteclick = keystate[SDLK_LALT] | keystate[SDLK_RALT]; + + if(vid.shifttarget) { + leftclick = false; + targetclick = keystate[SDLK_RSHIFT] | keystate[SDLK_LSHIFT]; + } + else { + leftclick = keystate[SDLK_RSHIFT]; + targetclick = true; + } + +#ifdef AUDIO + if(audio) handlemusic(); +#endif + SDL_Event ev; + DEB("react"); + + while(SDL_PollEvent(&ev)) { + int sym = 0; + int uni = 0; + ld shift = 1; + + if(ev.type == SDL_ACTIVEEVENT) { + if(ev.active.state & SDL_APPINPUTFOCUS) { + if(ev.active.gain) { + outoffocus = false; + } + else { + outoffocus = true; + } + } + } + + if(ev.type == SDL_VIDEORESIZE) { + vid.xres = ev.resize.w; + vid.yres = ev.resize.h; + vid.killreduction = 0; + setfsize = true; + setvideomode(); +#ifdef GL + glViewport(0, 0, vid.xres, vid.yres); +#endif + } + + if(ev.type == SDL_VIDEOEXPOSE) { + drawscreen(); + } + + if(ev.type == SDL_JOYAXISMOTION) { + if(ev.jaxis.value != 0 && + ev.jaxis.axis >= 2) + printf("which = %d axis = %d value = %d\n", + ev.jaxis.which, + ev.jaxis.axis, + ev.jaxis.value); + if(ev.jaxis.which == 0) { + if(ev.jaxis.axis == 0) + joyx = ev.jaxis.value; + else if(ev.jaxis.axis == 1) + joyy = ev.jaxis.value; + else if(ev.jaxis.axis == 3) + panjoyx = ev.jaxis.value; + else if(ev.jaxis.axis == 4) + panjoyy = ev.jaxis.value; + checkjoy(); + printf("panjoy = %d,%d\n", panjoyx, panjoyy); + } + else { + if(ev.jaxis.axis == 0) + panjoyx = ev.jaxis.value; + else + panjoyy = ev.jaxis.value; + } + } + + if(ev.type == SDL_JOYBUTTONDOWN) { + movepcto(joydir); + checkjoy(); + } + + if(ev.type == SDL_KEYDOWN) { + flashMessages(); + mousing = false; + sym = ev.key.keysym.sym; + uni = ev.key.keysym.unicode; + if(ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) shift = -1; + if(ev.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) shift /= 10; + } + + if(ev.type == SDL_MOUSEBUTTONDOWN) { + flashMessages(); + mousepressed = true; + mousing = true; + if(ev.button.button==SDL_BUTTON_RIGHT || leftclick) + sym = SDLK_F1; + else if(ev.button.button==SDL_BUTTON_MIDDLE || rightclick) + sym = 1; + else if(ev.button.button==SDL_BUTTON_WHEELUP) { + ld jx = (mousex - vid.xcenter - .0) / vid.radius / 10; + ld jy = (mousey - vid.ycenter - .0) / vid.radius / 10; + playermoved = false; + View = gpushxto0(hpxy(jx, jy)) * View; + sym = 1; + } + else { + sym = getcstat, uni = getcstat, shift = getcshift; + } + } + + if(ev.type == SDL_MOUSEBUTTONUP) + mousepressed = false; + + if(cmode != emScores) { +#ifndef PANDORA + if(sym == SDLK_RIGHT) View = xpush(-0.2*shift) * View, playermoved = false; + if(sym == SDLK_LEFT) View = xpush(+0.2*shift) * View, playermoved = false; + if(sym == SDLK_UP) View = ypush(+0.2*shift) * View, playermoved = false; + if(sym == SDLK_DOWN) View = ypush(-0.2*shift) * View, playermoved = false; +#endif + if(sym == SDLK_PAGEUP) View = spin(M_PI/21*shift) * View; + if(sym == SDLK_PAGEDOWN) View = spin(-M_PI/21*shift) * View; + } + + if(ev.type == SDL_MOUSEMOTION) { + hyperpoint mouseoh = mouseh; + + mousing = true; + mousex = ev.motion.x; + mousey = ev.motion.y; + mouseh = gethyper(mousex, mousey); + + if((rightclick || (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_MMASK)) && + !outofmap(mouseh) && !outofmap(mouseoh) && + mouseh[2] < 50 && mouseoh[2] < 50) { + panning(mouseoh, mouseh); + } + +#ifdef SIMULATE_JOYSTICK + // pretend that both joysticks are present + stick = panstick = (SDL_Joystick*) (&vid); + panjoyx = 20 * (mousex - vid.xcenter); + panjoyy = 20 * (mousey - vid.ycenter); + checkjoy(); +#endif + } + + DEB("r1"); + if(sym == SDLK_F7) { + + time_t timer; + timer = time(NULL); + char buf[128]; strftime(buf, 128, "shot-%y%m%d-%H%M%S.bmp", localtime(&timer)); + + SDL_SaveBMP(s, buf); + addMessage(XLAT("Screenshot saved to %1", buf)); + } + + DEB("r2"); + + if(cmode == emDraw) { + + hyperpoint mh = inverse(playertrans) * mouseh; + // inverse(playertrans) * + // mouseh; + + // spin(-M_PI/2) * mouseh; + + if(uni == 'n') { + dsCur->list.clear(); + dsCur->list.push_back(mh); +#ifdef GL + GL_initialized = false; +#endif + } + + if(uni == 'a') { + dsCur->list.push_back(mh); +#ifdef GL + GL_initialized = false; +#endif + } + + if(uni == 'u') { + if(!vid.female) loadShape(shPBody, 2, 0); + else loadShape(shFemaleBody, 2, 0); + + loadShape(shPSword, 1, 1); + + if(vid.female) + loadShape(shFemaleDress, 2, 2); + + if(vid.female) + loadShape(shFemaleHair, 2, 3); + else + loadShape(shPHead, 2, 3); + + loadShape(shPFace, 2, 4); + +#ifdef GL + GL_initialized = false; +#endif + } + + if(uni == 'm' || uni == 'd' || uni == 'c' || uni == 'b') { + int i = 0; + if(size(dsCur->list) < 2) continue; + for(int j=1; jlist); j++) + if(intval(mh, dsCur->list[j]) < intval(mh, dsCur->list[i])) + i = j; + if(uni == 'm') + dsCur->list[i] = mh; + if(uni == 'd') + dsCur->list.erase(dsCur->list.begin() + i); + if(uni == 'c') + dsCur->list.push_back(dsCur->list[i]); + if(uni == 'b') { + while(i) { + dsCur->list.push_back(dsCur->list[0]); + dsCur->list.erase(dsCur->list.begin()); + i--; + } + } +#ifdef GL + GL_initialized = false; +#endif + } + + if(uni == 'f') { + if(floordraw) dslayer++; else floordraw = true; + } + if(uni == 'p') { + if(!floordraw) dslayer++; else floordraw = false; + } + if(uni == 'g') ccenter = mouseh, crad += shift / 20; + + if(uni == '1') dsCur->rots = 1; + if(uni == '2') dsCur->rots = 2; + if(uni == '3') dsCur->rots = 3; + if(uni == '4') dsCur->rots = 4; + if(uni == '5') dsCur->rots = 5; + if(uni == '6') dsCur->rots = 6; + if(uni == '7') dsCur->rots = 7; + if(uni == '8') dsCur->rots = 8; + if(uni == '9') dsCur->rots = 21; + if(uni == '0') dsCur->sym = !dsCur->sym; + + if(uni == 't') dsCur->shift = mh; + if(uni == 'y') dsCur->spin = mh; + +#ifdef GL + if(uni == 't' || uni == 'y') GL_initialized = false; +#endif + + + if(uni == 's') { + for(int i=prehpc; i < qhpc; i++) { + for(int k=0; k<8; k++) + for(int j=0; j<3; j++) if(i == shUser[k][j].s) + printf("\n // group %d layer %d\n\n", j, k); + printf(" hpcpush(hpxyz(%f,%f,%f));\n", double(hpc[i][0]), double(hpc[i][1]), double(hpc[i][2])); + } + } + + if(uni == 'z') vid.alpha = -.5; + if(uni == 'o') vid.alpha = 1; + + saveImages(); + + if(sym == SDLK_F6) { + cmode = emNormal; + sym = 0; + } + + if(sym == SDLK_ESCAPE) cmode = emNormal; + + if(sym == SDLK_F1) { + cmode = emHelp; + sym = 0; + help = XLAT(drawhelp); + } + + if(sym == SDLK_F2) { + cmode = emVisual1; + sym = 0; + } + + if(sym == SDLK_F10) cmode = emNormal; + } + + if(cmode == emNormal) { + + if(!(uni >= 'A' && uni <= 'Z') && cwt.c->land != laGameBoard) { + if(sym == 'l' || sym == 'd' || sym == SDLK_KP6) movepckeydir(0); + if(sym == 'n' || sym == 'c' || sym == SDLK_KP3) movepckeydir(1); + if(sym == 'j' || sym == 'x' || sym == SDLK_KP2) movepckeydir(2); + if(sym == 'b' || sym == 'z' || sym == SDLK_KP1) movepckeydir(3); + if(sym == 'h' || sym == 'a' || sym == SDLK_KP4) movepckeydir(4); + if(sym == 'y' || sym == 'q' || sym == SDLK_KP7) movepckeydir(5); + if(sym == 'k' || sym == 'w' || sym == SDLK_KP8) movepckeydir(6); + if(sym == 'u' || sym == 'e' || sym == SDLK_KP9) movepckeydir(7); + } + +#ifdef PANDORA + if(sym == SDLK_RIGHT) movepckeydir(0); + if(sym == SDLK_LEFT) movepckeydir(4); + if(sym == SDLK_DOWN) movepckeydir(2 + (leftclick?1:0) - (rightclick?1:0)); + if(sym == SDLK_UP) movepckeydir(6 - (leftclick?1:0) + (rightclick?1:0)); +#endif + + if(cheater) + applyCheat(uni, mouseover); + + if(cwt.c->land == laGameBoard) + applyGameBoard(uni, sym, mouseover, vid.boardmode); + else { + if(sym == '.' || sym == 's') movepcto(-1); + if((sym == SDLK_DELETE || sym == SDLK_KP_PERIOD || sym == 'g') && uni != 'G' && uni != 'G'-64) + movepcto(-2); + if(sym == 't' && uni != 'T' && uni != 'T'-64) { + targetRangedOrb(centerover, roKeyboard); + } + } + + if(sym == SDLK_KP5) movepcto(-1); + + // if(sym == SDLK_F4) restartGameSwitchEuclid(); + + if(sym == SDLK_F5) restartGame(); + if(sym == SDLK_ESCAPE) { + cmode = emQuit; + achievement_final(false); + if(!canmove) { + addMessage(XLAT("GAME OVER")); + addMessage(timeline()); + } + msgscroll = 0; + } + if(sym == SDLK_F10) return; + + if(!canmove) { + if(sym == SDLK_RETURN) return; + else if(uni == 'r') restartGame(); + else if(uni == 't') { + restartGame(); + loadScores(); + } + } + + if(sym == SDLK_HOME || sym == SDLK_F3 || sym == ' ') { + if(playerfound) centerpc(INF); + else { + View = Id; + // EUCLIDEAN + if(!euclid) viewctr.h = cwt.c->master; + else centerover = cwt.c; + // SDL_LockSurface(s); + drawthemap(); + // SDL_UnlockSurface(s); + centerpc(INF); + } + playermoved = true; + } + + if(sym == SDLK_F6) { + View = spin(M_PI/2) * inverse(cwtV) * View; + if(flipplayer) View = spin(M_PI) * View; + cmode = emDraw; + } + + if(sym == 'v' || sym == SDLK_F2) { + cmode = emVisual1; + } + +#ifdef PANDORA + if(ev.type == SDL_MOUSEBUTTONUP && sym == 0 && !rightclick) { +#else + if(ev.type == SDL_MOUSEBUTTONDOWN && sym == 0 && !rightclick) { +#endif + + bool forcetarget = (keystate[SDLK_RSHIFT] | keystate[SDLK_LSHIFT]); + + if(mouseover && targetclick && targetRangedOrb(mouseover, forcetarget ? roMouseForce : roMouse)) + ; + else if(forcetarget) + ; + else if(mousedest == -1) + movepcto(mousedest); + else + movepcto((mousedest + 42 - cwt.spin)%42); + } + + if(sym == SDLK_F1) { + cmode = emHelp; + } + } + + else if(cmode == emVisual1) { + + char xuni = uni | 96; + + if(uni >= 32 && uni < 64) xuni = uni; + + if(uni == ' ') cmode = emVisual2; + + if(xuni == 'p') vid.alpha += shift * 0.1; + if(xuni == 'z') vid.scale += shift * 0.1; + if(xuni == 'a') vid.aspeed += shift; + if(xuni == 'f') { + vid.full = !vid.full; + if(shift > 0) { + vid.xres = vid.full ? vid.xscr : 9999; + vid.yres = vid.full ? vid.yscr : 9999; + setfsize = true; + } + setvideomode(); + } + + if(xuni == 'v' || sym == SDLK_F2) cmode = emNormal; + if(xuni == 's') saveConfig(); + + if(xuni == '7') { vid.darkhepta = !vid.darkhepta; } + if(xuni == 'w') { vid.wallmode += 60 + (shift > 0 ? 1 : -1); vid.wallmode %= 4; } + if(xuni == 'm') { vid.monmode += 60 + (shift > 0 ? 1 : -1); vid.monmode %= 4; } + if(xuni == 'c') { vid.axes += 60 + (shift > 0 ? 1 : -1); vid.axes %= 4; } + if(xuni == 'b') { + audiovolume += int(10.5 * shift); + if(audiovolume < 0) audiovolume = 0; + if(audiovolume > MIX_MAX_VOLUME) audiovolume = MIX_MAX_VOLUME; + Mix_VolumeMusic(audiovolume); + } + + if(sym == SDLK_ESCAPE) cmode = emNormal; + +#ifdef SHOWOFF + process_showoff(sym); +#endif + + if(sym == SDLK_F1 || sym == 'h') { + cmode = emHelp; + } + + if(xuni == 'l') { + vid.language++; + vid.language %= NUMLAN; + printf("lan = %d\n", vid.language); + } + + if(xuni == 'g') { + vid.female = !vid.female; + switchcolor(vid.skincolor, skincolors, 0); + switchcolor(vid.haircolor, haircolors, 0); + switchcolor(vid.dresscolor, dresscolors, 0); + switchcolor(vid.swordcolor, swordcolors, 0); + cmode = emCustomizeChar; + } + + } + + else if(cmode == emCustomizeChar) { + char xuni = uni | 96; + int mod = ev.key.keysym.mod; + if(shift < -.5) + mod = 1; + else if(shift > -.2 && shift < .2) + mod = 2; + else mod = 0; + if(xuni == 'g') vid.female = !vid.female; + if(xuni == 's') switchcolor(vid.skincolor, skincolors, mod); + if(xuni == 'h') switchcolor(vid.haircolor, haircolors, mod); + if(xuni == 'w') switchcolor(vid.swordcolor, swordcolors, mod); + if(xuni == 'd') switchcolor(vid.dresscolor, dresscolors, mod); + if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal; + } + + else if(cmode == emVisual2) { + char xuni = uni | 96; + +#ifdef GL + if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal; + + if(xuni == 'o' && shift > 0) { + vid.usingGL = !vid.usingGL; + if(vid.usingGL) addMessage(XLAT("openGL mode enabled")); + if(!vid.usingGL) addMessage(XLAT("openGL mode disabled")); + setvideomode(); + } + + if(xuni == 'o' && shift < 0 && !vid.usingGL) { + vid.usingAA = !vid.usingAA; + if(vid.usingAA) addMessage(XLAT("anti-aliasing enabled")); + if(!vid.usingAA) addMessage(XLAT("anti-aliasing disabled")); + } +#endif + + if(xuni == 'f') { + vid.framelimit += int(10.5 * shift); + if(vid.framelimit < 5) vid.framelimit = 5; + } + + if(xuni == 'a') vid.joyvalue += int(shift * 100); + if(xuni == 'b') vid.joyvalue2 += int(shift * 100); + if(xuni == 'c') vid.joypanthreshold += int(shift * 100); + if(xuni == 'd') vid.joypanspeed += shift / 50000; + if(xuni == 'e') vid.eye += shift * 0.01; + if(xuni == 't') vid.flashtime += shift>0?1:-1; + + if(xuni == 'p') autojoy = !autojoy; + if(xuni == 's') { vid.shifttarget = !vid.shifttarget; } + + if(uni == ' ') cmode = emChangeMode; + } + + else if(cmode == emChangeMode) { + + char xuni = uni | 96; + if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal; + if(uni == ' ') cmode = emVisual1; + + if(sym == 'c') { + cheater++; + addMessage(XLAT("You activate your demonic powers!")); + addMessage(XLAT("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.")); + cmode = emNormal; + } + + if(xuni == 'g') cmode = emDraw; + if(xuni == 'e') cmode = emPickEuclidean; + + if(uni == 'h' || uni == '3' || uni == '7' || uni == 'f') { + vid.boardmode = uni; + cheater = 1; + showid = 0; firstland = laGameBoard; + for(int i=0; i= 'a' && xuni < 'a' + landtypes) { + euclidland = eLand(2 + (xuni - 'a')); + if(landvisited[euclidland]) { + if(euclid) restartGame(); + else restartGameSwitchEuclid(); + cmode = emNormal; + } + else euclidland = laIce; + } + } + + else if(cmode == emHelp) { + if(sym == SDLK_F1 && help != "@") + help = "@"; + else if(uni == 'c') + help = buildCredits(); + else if((sym != 0 && sym != SDLK_F12) || ev.type == SDL_MOUSEBUTTONDOWN) + cmode = (help == XLAT(drawhelp) ? emDraw : emNormal); + } + + else if(cmode == emQuit) { + if(sym == SDLK_RETURN || sym == SDLK_F10) return; + else if(uni == 'r' || sym == SDLK_F5) { + restartGame(), cmode = emNormal; + msgs.clear(); + } + else if(sym == SDLK_UP || sym == SDLK_KP8) msgscroll++; + else if(sym == SDLK_DOWN || sym == SDLK_KP2) msgscroll--; + else if(sym == SDLK_PAGEUP || sym == SDLK_KP9) msgscroll+=5; + else if(sym == SDLK_PAGEDOWN || sym == SDLK_KP3) msgscroll-=5; + else if(uni == 't') { + if(!canmove) restartGame(); + loadScores(); + msgs.clear(); + } + + else if((sym != 0 && sym != SDLK_F12) || ev.type == SDL_MOUSEBUTTONDOWN) { + cmode = emNormal; + msgs.clear(); + } + } + + else if(cmode == emScores) + handleScoreKeys(sym, ev); + + else if(cmode == emPickScores) + handlePickScoreKeys(uni, ev); + + if(ev.type == SDL_QUIT) + return; + + DEB("r3"); + } + + if(playerdead) break; + } + + } +#endif + +#ifndef MOBILE +void cleargraph() { + for(int i=0; i<256; i++) if(font[i]) TTF_CloseFont(font[i]); + for(int i=0; i<128; i++) if(glfont[i]) delete glfont[i]; +#ifndef SIMULATE_JOYSTICK + if(stick) SDL_JoystickClose(stick); + if(panstick) SDL_JoystickClose(panstick); +#endif + SDL_Quit(); + } +#endif + +void cleargraphmemory() { + mouseover = centerover = lmouseover = NULL; + } + diff --git a/heptagon.cpp b/heptagon.cpp new file mode 100644 index 00000000..22f805b5 --- /dev/null +++ b/heptagon.cpp @@ -0,0 +1,158 @@ +// Hyperbolic Rogue +// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details + +// heptagon here refers to underlying heptagonal tesselation +// (which you can see by changing the conditions in graph.cpp) + +// automaton state +enum hstate { hsOrigin, hsA, hsB, hsError }; + +int fixrot(int a) { return (a+98)% 7; } +int fix42(int a) { return (a+420)% 42; } + +struct heptagon; + +struct cell; +cell *newCell(int type, heptagon *master); + +struct heptagon { + // automaton state + hstate s : 8; + // we are spin[i]-th neighbor of move[i] + unsigned char spin[7]; + // neighbors; move[0] always goes towards origin, + // and then we go clockwise + heptagon* move[7]; + // distance from the origin + short distance; + // fjord/wineyard generator + short fjordval; + heptagon*& modmove(int i) { return move[fixrot(i)]; } + unsigned char& gspin(int i) { return spin[fixrot(i)]; } + cell *c7; + // associated generator of alternate structure, for Camelot and horocycles + heptagon *alt; + }; + +// the automaton is used to generate each heptagon in an unique way +// (you can see the tree obtained by changing the conditions in graph.cpp) +// from the origin we can go further in any direction, and from other heptagons +// we can go in directions 3 and 4 (0 is back to origin, so 3 and 4 go forward), +// and sometimes in direction 5 + +hstate transition(hstate s, int dir) { + if(s == hsOrigin) return hsA; + if(s == hsA && dir >= 3 && dir <= 4) return hsA; + if(s == hsA && dir == 5) return hsB; + if(s == hsB && dir == 4) return hsB; + if(s == hsB && dir == 3) return hsA; + return hsError; + } + +heptagon origin; +vector allAlts; + +// create h->move[d] if not created yet +heptagon *createStep(heptagon *h, int d); + +// create a new heptagon +heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) { + heptagon *h = new heptagon; + h->alt = NULL; + h->s = s; + for(int i=0; i<7; i++) h->move[i] = NULL; + h->move[pard] = parent; h->spin[pard] = d; + parent->move[d] = h; parent->spin[d] = pard; + if(parent->c7) { + h->c7 = newCell(7, h); + h->fjordval = fjord_heptagon(parent->fjordval, d); + } + else { + h->c7 = NULL; + h->fjordval = 0; + } +//generateFjordval(parent); +//generateFjordval(h); + if(pard == 0) { + if(parent->s == hsOrigin) h->distance = 2; + else if(h->spin[0] == 5) + h->distance = parent->distance + 1; + else if(h->spin[0] == 4 && h->move[0]->s == hsB) + h->distance = createStep(h->move[0], (h->spin[0]+2)%7)->distance + 3; + else h->distance = parent->distance + 2; + } + else h->distance = parent->distance - 2; + return h; + } + +void addSpin(heptagon *h, int d, heptagon *from, int rot, int spin) { + rot = fixrot(rot); + createStep(from, rot); + h->move[d] = from->move[rot]; + h->spin[d] = fixrot(from->spin[rot] + spin); + h->move[d]->move[fixrot(from->spin[rot] + spin)] = h; + h->move[d]->spin[fixrot(from->spin[rot] + spin)] = d; +//generateFjordval(h->move[d]); generateFjordval(h); + } + +heptagon *createStep(heptagon *h, int d) { + d = fixrot(d); + if(h->s != hsOrigin && !h->move[0]) { + buildHeptagon(h, 0, hsA, 4); + } + if(h->move[d]) return h->move[d]; + if(h->s == hsOrigin) { + buildHeptagon(h, d, hsA); + } + else if(d == 1) { + addSpin(h, d, h->move[0], h->spin[0]-1, -1); + } + else if(d == 6) { + addSpin(h, d, h->move[0], h->spin[0]+1, +1); + } + else if(d == 2) { + createStep(h->move[0], h->spin[0]-1); + addSpin(h, d, h->move[0]->modmove(h->spin[0]-1), 5 + h->move[0]->gspin(h->spin[0]-1), -1); + } + else if(d == 5 && h->s == hsB) { + createStep(h->move[0], h->spin[0]+1); + addSpin(h, d, h->move[0]->modmove(h->spin[0]+1), 2 + h->move[0]->gspin(h->spin[0]+1), +1); + } + else + buildHeptagon(h, d, (d == 5 || (h->s == hsB && d == 4)) ? hsB : hsA); + return h->move[d]; + } + +// a structure used to walk on the heptagonal tesselation +// (remembers not only the heptagon, but also direction) +struct heptspin { + heptagon *h; + int spin; + }; + +heptspin hsstep(const heptspin &hs, int spin) { + createStep(hs.h, hs.spin); + heptspin res; + res.h = hs.h->move[hs.spin]; + res.spin = fixrot(hs.h->spin[hs.spin] + spin); + return res; + } + +heptspin hsspin(const heptspin &hs, int val) { + heptspin res; + res.h = hs.h; + res.spin = fixrot(hs.spin + val); + return res; + } + +// display the coordinates of the heptagon +void backtrace(heptagon *pos) { + if(pos == &origin) return; + backtrace(pos->move[0]); + printf(" %d", pos->spin[0]); + } + +void hsshow(const heptspin& t) { + printf("ORIGIN"); backtrace(t.h); printf(" (spin %d)\n", t.spin); + } + diff --git a/hr-icon.ico b/hr-icon.ico new file mode 100644 index 00000000..c647ba5c Binary files /dev/null and b/hr-icon.ico differ diff --git a/hr3-caves.ogg b/hr3-caves.ogg new file mode 100644 index 00000000..ea5bdbcb Binary files /dev/null and b/hr3-caves.ogg differ diff --git a/hr3-crossroads.ogg b/hr3-crossroads.ogg new file mode 100644 index 00000000..064f6839 Binary files /dev/null and b/hr3-crossroads.ogg differ diff --git a/hr3-desert.ogg b/hr3-desert.ogg new file mode 100644 index 00000000..35d967a9 Binary files /dev/null and b/hr3-desert.ogg differ diff --git a/hr3-graveyard.ogg b/hr3-graveyard.ogg new file mode 100644 index 00000000..b7db8191 Binary files /dev/null and b/hr3-graveyard.ogg differ diff --git a/hr3-hell.ogg b/hr3-hell.ogg new file mode 100644 index 00000000..9de328e0 Binary files /dev/null and b/hr3-hell.ogg differ diff --git a/hr3-icyland.ogg b/hr3-icyland.ogg new file mode 100644 index 00000000..97fbcd80 Binary files /dev/null and b/hr3-icyland.ogg differ diff --git a/hr3-jungle.ogg b/hr3-jungle.ogg new file mode 100644 index 00000000..49a5429f Binary files /dev/null and b/hr3-jungle.ogg differ diff --git a/hr3-laboratory.ogg b/hr3-laboratory.ogg new file mode 100644 index 00000000..551202ad Binary files /dev/null and b/hr3-laboratory.ogg differ diff --git a/hr3-mirror.ogg b/hr3-mirror.ogg new file mode 100644 index 00000000..9c67fb73 Binary files /dev/null and b/hr3-mirror.ogg differ diff --git a/hr3-motion.ogg b/hr3-motion.ogg new file mode 100644 index 00000000..d4386d83 Binary files /dev/null and b/hr3-motion.ogg differ diff --git a/hr3-rlyeh.ogg b/hr3-rlyeh.ogg new file mode 100644 index 00000000..76444018 Binary files /dev/null and b/hr3-rlyeh.ogg differ diff --git a/hyper.cpp b/hyper.cpp new file mode 100644 index 00000000..baec6040 --- /dev/null +++ b/hyper.cpp @@ -0,0 +1,200 @@ +// Hyperbolic Rogue +// Copyright (C) 2011 Zeno Rogue + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +// disable for the Android version +#define ISANDROID 0 +#define ISMOBILE 0 +#define ISIOS 0 +#define VER "6.6" +#define VERNUM 6600 +#define VERNUM_HEX 0x6600 + +#include + +#ifndef MAC +#undef main +#endif + +#include +#include +#include +#include +#include +#include + +using namespace std; + +const char *scorefile = "hyperrogue.log"; +const char *conffile = "hyperrogue.ini"; +const char *musicfile = ""; + +typedef long double ld; + +template int size(T& x) {return x.size(); } +string its(int i) { char buf[64]; sprintf(buf, "%d", i); return buf; } +string fts(float x) { char buf[64]; sprintf(buf, "%4.2f", x); return buf; } + +#undef DEBT +void DEBT(const char *buf) { + printf("%4d %s\n", SDL_GetTicks(), buf); + } + +string s0; +void addMessage(string s, char spamtype = 0); + +int clWidth, clHeight, clFont; +string commandline; + +#include "hyperpoint.cpp" +#include "fjordgen.cpp" +#include "heptagon.cpp" +#include "classes.cpp" +#include "language.cpp" + +#ifdef STEAM +#define NOLICENSE +#endif + +#include "achievement.h" + +#include "cell.cpp" +#include "game.cpp" +#include "graph.cpp" + +#include "achievement.cpp" + +#include + + +bool switchEuclid = false; + +int main(int argc, char **argv) { + + printf("HyperRogue by Zeno Rogue , version "VER"\n"); +#ifndef NOLICENSE + printf("released under GNU General Public License version 2 and thus\n"); + printf("comes with absolutely no warranty; see COPYING for details\n"); +#endif + + achievement_init(); + + // printf("cell size = %d\n", int(sizeof(cell))); + srand(time(NULL)); + + #ifdef FHS + char sbuf[640], cbuf[640]; + if(getenv("HOME")) { + snprintf(sbuf, 640, "%s/.%s", getenv("HOME"), scorefile); scorefile = sbuf; + snprintf(cbuf, 640, "%s/.%s", getenv("HOME"), conffile); conffile = cbuf; + } + #endif + + for(int i=1; i= 0; uu--) { + printf("uu=%d\n", uu); + initgame(uu); + restartGame(); + } */ + + eLand f = firstland; + + loadsave(); + initgame(); + + restoreGolems(items[itOrbLife]); items[itOrbLife] = 0; + + firstland = f; + // exit(1); + + initgraph(); + + int t1 = SDL_GetTicks(); + + if(switchEuclid) restartGameSwitchEuclid(); + + mainloop(); + + achievement_final(!items[itOrbSafety]); + SDL_Quit(); + + saveStats(); + int msec = SDL_GetTicks() - t1; + printf("frame : %f ms (%f fps)\n", 1.*msec/frames, 1000.*frames/msec); + clearMemory(); + cleargraph(); + + achievement_close(); + + return 0; + } diff --git a/hyper.exe b/hyper.exe new file mode 100755 index 00000000..407cb24b Binary files /dev/null and b/hyper.exe differ diff --git a/hyper.rc b/hyper.rc new file mode 100644 index 00000000..71d7a111 --- /dev/null +++ b/hyper.rc @@ -0,0 +1,26 @@ +id ICON "hr-icon.ico" + +1 VERSIONINFO +FILEVERSION 5,5,1,0 +PRODUCTVERSION 5,5,1,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "Zeno Rogue" + VALUE "FileDescription", "A roguelike in non-euclidean space" + VALUE "FileVersion", "55a" + VALUE "InternalName", "hyper" + VALUE "LegalCopyright", "Zeno Rogue" + VALUE "OriginalFilename", "hyper.exe" + VALUE "ProductName", "HyperRogue" + VALUE "ProductVersion", "5.5a" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/hyperpoint.cpp b/hyperpoint.cpp new file mode 100644 index 00000000..8c65c76f --- /dev/null +++ b/hyperpoint.cpp @@ -0,0 +1,250 @@ +// Hyperbolic Rogue +// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details + +// for the Euclidean mode... +bool euclid = false; + +// hyperbolic points and matrices + +// basic functions and types +//=========================== + +ld sinh(ld alpha) { return (exp(alpha) - exp(-alpha)) / 2; } +ld cosh(ld alpha) { return (exp(alpha) + exp(-alpha)) / 2; } + +ld squar(ld x) { return x*x; } + +int sig(int z) { return z<2?1:-1; } + +// hyperbolic point: +//=================== + +// we represent the points on the hyperbolic plane +// by points in 3D space (Minkowski space) such that x^2+y^2-z^2 == -1, z > 0 +// (this is analogous to representing a sphere with points such that x^2+y^2+z^2 == 1) + +struct hyperpoint { + ld tab[3]; + ld& operator [] (int i) { return tab[i]; } + const ld& operator [] (int i) const { return tab[i]; } + }; + +hyperpoint hpxyz(ld x, ld y, ld z) { + // EUCLIDEAN + hyperpoint r; r[0] = x; r[1] = y; r[2] = z; return r; + } + +hyperpoint hpxy(ld x, ld y) { + // EUCLIDEAN + return hpxyz(x,y, euclid ? 1 : 1+x*x+y*y); + } + +// center of the pseudosphere +hyperpoint Hypc = { {0,0,0} }; + +// origin of the hyperbolic plane +hyperpoint C0 = { {0,0,1} }; + +// a point (I hope this number needs no comments ;) ) +hyperpoint Cx1 = { {1,0,1.41421356237} }; + +// this function returns approximate square of distance between two points +// (in the spherical analogy, this would be the distance in the 3D space, +// through the interior, not on the surface) +// 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) { + return squar(h1[0]-h2[0]) + squar(h1[1]-h2[1]) - squar(h1[2]-h2[2]); + } + +// display a hyperbolic point +char *display(const hyperpoint& H) { + static char buf[100]; + sprintf(buf, "%8.4f:%8.4f:%8.4f", double(H[0]), double(H[1]), double(H[2])); + return buf; + } + +// get the center of the line segment from H1 to H2 +hyperpoint mid(const hyperpoint& H1, const hyperpoint& H2) { + + hyperpoint H3; + H3[0] = H1[0] + H2[0]; + H3[1] = H1[1] + H2[1]; + H3[2] = H1[2] + H2[2]; + + ld Z = 2; + + if(!euclid) { + Z = intval(H3, Hypc); + Z = sqrt(-Z); + } + + for(int c=0; c<3; c++) H3[c] /= Z; + + return H3; + } + +// matrices +//========== + +// matrices represent isometries of the hyperbolic plane +// (just like isometries of the sphere are represented by rotation matrices) + +struct transmatrix { + ld tab[3][3]; + ld * operator [] (int i) { return tab[i]; } + const ld * operator [] (int i) const { return tab[i]; } + }; + +// identity matrix +transmatrix Id = {{{1,0,0}, {0,1,0}, {0,0,1}}}; + +hyperpoint operator * (const transmatrix& T, const hyperpoint& H) { + hyperpoint z; + for(int i=0; i<3; i++) { + z[i] = 0; + for(int j=0; j<3; j++) z[i] += T[i][j] * H[j]; + } + return z; + } + +transmatrix operator * (const transmatrix& T, const transmatrix& U) { + transmatrix R; + for(int i=0; i<3; i++) for(int j=0; j<3; j++) R[i][j] = 0; + for(int i=0; i<3; i++) for(int j=0; j<3; j++) for(int k=0; k<3; k++) + R[i][j] += T[i][k] * U[k][j]; + return R; + } + +// rotate by alpha degrees +transmatrix spin(ld alpha) { + transmatrix T = Id; + T[0][0] = +cos(alpha); T[0][1] = +sin(alpha); + T[1][0] = -sin(alpha); T[1][1] = +cos(alpha); + T[2][2] = 1; + return T; + } + +transmatrix eupush(ld x, ld y) { + transmatrix T = Id; + T[0][2] = x; + T[1][2] = y; + return T; + } + +// push alpha units to the right +transmatrix xpush(ld alpha) { + if(euclid) return eupush(alpha, 0); + transmatrix T = Id; + T[0][0] = +cosh(alpha); T[0][2] = +sinh(alpha); + T[2][0] = +sinh(alpha); T[2][2] = +cosh(alpha); + return T; + } + +// push alpha units vertically +transmatrix ypush(ld alpha) { + if(euclid) return eupush(0, alpha); + transmatrix T = Id; + T[1][1] = +cosh(alpha); T[1][2] = +sinh(alpha); + T[2][1] = +sinh(alpha); T[2][2] = +cosh(alpha); + return T; + } + +// rotate the hyperplane around C0 such that H[1] == 0 and H[0] >= 0 +transmatrix spintox(hyperpoint H) { + transmatrix T = Id; + ld R = sqrt(H[0] * H[0] + H[1] * H[1]); + if(R >= 1e-12) { + T[0][0] = +H[0]/R; T[0][1] = +H[1]/R; + T[1][0] = -H[1]/R; T[1][1] = +H[0]/R; + } + return T; + } + +// reverse of spintox(H) +transmatrix rspintox(hyperpoint H) { + transmatrix T = Id; + ld R = sqrt(H[0] * H[0] + H[1] * H[1]); + if(R >= 1e-12) { + T[0][0] = +H[0]/R; T[0][1] = -H[1]/R; + T[1][0] = +H[1]/R; T[1][1] = +H[0]/R; + } + return T; + } + +// for H such that H[1] == 0, this matrix pushes H to C0 +transmatrix pushxto0(hyperpoint H) { + if(euclid) return eupush(-H[0], -H[1]); + transmatrix T = Id; + T[0][0] = +H[2]; T[0][2] = -H[0]; + T[2][0] = -H[0]; T[2][2] = +H[2]; + return T; + } + +// reverse of pushxto0(H) +transmatrix rpushxto0(hyperpoint H) { + if(euclid) return eupush(H[0], H[1]); + transmatrix T = Id; + T[0][0] = +H[2]; T[0][2] = +H[0]; + T[2][0] = +H[0]; T[2][2] = +H[2]; + return T; + } + +// generalization: H[1] can be non-zero +transmatrix gpushxto0(hyperpoint H) { + hyperpoint H2 = spintox(H) * H; + return rspintox(H) * pushxto0(H2) * spintox(H); + } + +transmatrix rgpushxto0(hyperpoint H) { + hyperpoint H2 = spintox(H) * H; + return rspintox(H) * rpushxto0(H2) * spintox(H); + } + + +// fix the matrix T so that it is indeed an isometry +// (without using this, imprecision could accumulate) + +void fixmatrix(transmatrix& T) { + for(int x=0; x<3; x++) for(int y=0; y<=x; y++) { + ld dp = 0; + for(int z=0; z<3; z++) dp += T[z][x] * T[z][y] * sig(z); + + if(y == x) dp = 1 - sqrt(sig(x)/dp); + + for(int z=0; z<3; z++) T[z][x] -= dp * T[z][y]; + } + } + +// show the matrix on screen + +void display(const transmatrix& T) { + for(int y=0; y<3; y++) { + for(int x=0; x<3; x++) printf("%10.7f", double(T[y][x])); + printf(" -> %10.7f\n", double(squar(T[y][0]) + squar(T[y][1]) - squar(T[y][2]))); + // printf("\n"); + } + for(int x=0; x<3; x++) printf("%10.7f", double(squar(T[0][x]) + squar(T[1][x]) - squar(T[2][x]))); printf("\n"); + for(int x=0; x<3; x++) { + int y = (x+1) % 3; + printf("%10.7f", double(T[0][x]*T[0][y] + T[1][x]*T[1][y] - T[2][x]*T[2][y])); + } + printf("\n\n"); + } + +transmatrix inverse(transmatrix T) { + ld det = 0; + for(int i=0; i<3; i++) + det += T[0][i] * T[1][(i+1)%3] * T[2][(i+2)%3]; + for(int i=0; i<3; i++) + det -= T[0][i] * T[1][(i+2)%3] * T[2][(i+1)%3]; + + transmatrix T2; + if(det == 0) return T2; + + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + T2[j][i] = (T[(i+1)%3][(j+1)%3] * T[(i+2)%3][(j+2)%3] - T[(i+1)%3][(j+2)%3] * T[(i+2)%3][(j+1)%3]) / det; + + return T2; + } diff --git a/hyperrogue-music.txt b/hyperrogue-music.txt new file mode 100644 index 00000000..8940cd45 --- /dev/null +++ b/hyperrogue-music.txt @@ -0,0 +1,33 @@ +# Crossroads [02] +[02] */hr3-crossroads.ogg +# Desert [03] +[03] */hr3-desert.ogg +# Icy Lands [04] +[04] */hr3-icyland.ogg +# Living Caves [05] +[05] */hr3-caves.ogg +# Jungle [06] +[06] */hr3-jungle.ogg +# Alchemist's Lab [07] +[07] */hr3-laboratory.ogg +# Mirror [08] +[08] */hr3-mirror.ogg +# Graveyard [09] +[09] */hr3-graveyard.ogg +# R'Lyeh [10] +[10] */hr3-rlyeh.ogg +# Hell [11] +[11] */hr3-hell.ogg +# Cheaterland [12] +[12] */hr3-icyland.ogg +# Motion [13] +[13] */hr3-motion.ogg +# Dry Forest [14] +[14] */hr3-jungle.ogg +# Game Board [15] +[15] */hr3-laboratory.ogg +# Barrier [01] (useless) +# None [00] (used when the window is out of focus) + + +HyperRogue soundtrack by Shawn Parrotte (http://www.shawnparrotte.com), under the Creative Commons BY-SA 3.0 license, http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/hyperrogue.html b/hyperrogue.html new file mode 100644 index 00000000..ed9030b1 --- /dev/null +++ b/hyperrogue.html @@ -0,0 +1,107 @@ + + + +HyperRogue + + + +

@ HyperRogue

+
Current version: 5.5a (Feb 15, 2014)
+
+ +

The game

+You are a lone outsider in a +strange, non-Euclidean world. +You can move with the numpad, vi keys (hjklyubn), or mouse. +You can also skip turns by pressing ".".

+ +As a Rogue, your goal is to collect as many treasures as possible. However, collecting treasures attracts dangerous monsters +(on the other hand, killing the monsters allows more treasures to be generated).

+ +You can kill most monsters by moving into them. Similarly, if the monster was next to you at the end of your +turn, it would kill you. The game protects you from getting yourself killed accidentally by ignoring moves which +lead to instant death (similar to the check rule from Chess). +

+Ultimately, you will probably run into a situation where monsters surround you. That means that your adventure +is over, and you will have to teleport back to the Euclidean world to survive by pressing Escape (quit). +

+Collecting enough treasure also allows you to find rare magical orbs, which grant you one-time or time-limited +special abilities. +

+The world is a combination of thirteen types of lands. Each land type has specific style (monsters, treasure, +magical orbs, terrain features). Collecting treasures only attracts more monsters in lands of the same type, +so you can try to collect lots of treasure in several different lands! +

+Some of these lands are available from the beginning, others can be found only if you have proven yourself +(press ESC to know what you should do to access more lands). Ultimately, you will be able to access Hell, +and look for the fabulous Orbs of Yendor which are hidden there. Get at least one of them to prove that you are +a true winner! Only the best players will be able to face the challenges of Hell, but both the monsters and the +challenges associated with the Orbs of Yendor are different than in the rest of the game, so it should be worth it. +

+You can see tooltips by placing the mouse over stuff. You can also right click to get more information +about game objects. +

+[desktop only] +Press v to configure the game. You can also rotate the world by pressing arrow keys, PageUp and +PageDn (not numpad). You can center on the PC by pressing Home.

+Your scores and other stats about your games are recorded to file +hyperrogue.log (in Linux, ~/.hyperrogue.log). You can save your configation to file +hyperrogue.ini (in Linux, ~/.hyperrogue.ini). + +
+
See the website for some screenshots, and more detailed and up-to-date information!
+
+ +The surface the game is played on is called a hyperbolic plane. It seems there is just a very +small amount of games and other works of art which use hyperbolic geometry (the most well +known are some works of M.C.Escher).

+The game dynamically generates new parts of the world as you move. Due to nature of the +hyperbolic plane, the chances that you get back to a place where you have been before +are very low (unless you go back exactly the same way). See more information about the geometry +used on the blog. +

+You can aim for the Orb of Yendor, or you can simply aim for as high score as possible. +My best so far is $175 but it should be beatable (I mean, I have won fairly only once, +and that was my end score in the winning game). + +

Technical information

+ +The HyperRogue package includes a Windows executable, documentation, and C++ source which has been tested under Linux +(you need SDL, SDL_ttf, and SDL_gfx). You should be able to compile on Ubuntu (or similar) with something like this: + +

+ +sudo apt-get install gcc libsdl1.2-dev libsdl-ttf2.0-dev libsdl-gfx1.2-dev
+unzip hyperrogue-55.zip
+cd hyperrogue-55
+make +
+

+It should also compile under MacOS with something like make -f Makefile.mac (note: I have no +access to a MacOS machine to test this makefile myself, it is based on + +this post by Konstantin Stupnik). +

+ +Released under +GNU General Public License, version 2. +As such, it comes with without any warranty. +

+ +
+ +If you would like to thank me for HyperRogue, +donations are welcome. + +
+ +You can contact me at zeno@attnam.com, or at +RogueTemple +or New Attnam forums (Z), or +at my blog. +
+ +
+ +
See my other games and stuff

+ diff --git a/hypersteam.cpp b/hypersteam.cpp new file mode 100644 index 00000000..1128fe2c --- /dev/null +++ b/hypersteam.cpp @@ -0,0 +1,249 @@ +// PRIVATE + +#define HAVE_ACHIEVEMENTS +#define LEADERFULL "Steam Leaderboards" +#define LEADER "Steam" + +#ifdef STEAMWIN +#include "sdk-w/public/steam/steam_api.h" +#else +#include "sdk/public/steam/steam_api.h" +#endif + +#include "steamvisualinterface.h" + +#define NOLICENSE + +unsigned steam_appid; +SteamLeaderboard_t steamleader[NUMLEADER]; + +int lastleader; + +void findLeaderboards() { + lastleader = ticks; + for(int i=0; iFindLeaderboard(leadernames[i]); + if(!hSteamAPICall) { + printf("Failed to look for leaderboard named '%s'\n", leadernames[i]); + } + else { + register_callback(hSteamAPICall); + return; + } + } + for(int i=0; iDownloadLeaderboardEntries( + steamleader[i], k_ELeaderboardDataRequestGlobalAroundUser, 0, 0); + register_callback_download(hSteamAPICall); + } + } + +CSteamID whoami; + +void OnUserStatsReceived( UserStatsReceived_t *pCallback ) { + if(steam_appid != pCallback->m_nGameID) + return; + if(pCallback->m_eResult == k_EResultOK) { + printf("Received stats and achievements from Steam\n" ); + whoami = pCallback->m_steamIDUser; + +/* string s = SteamUserStats()->GetAchievementDisplayAttribute("DIAMOND1", "name"); + printf("Achievement name: '%s'\n", s.c_str()); + + if(s == "Ice Explorer") { + printf("Steam language is English\n"); + default_language = 0; + } + else if(s == "Eksplorator") { + printf("Steam language is Polish\n"); + default_language = 1; + } + else if(s == "Buz Kâşifi") { + printf("Steam language is Turkish\n"); + default_language = 2; + } + else if(s == "Průzkumník Ledu") { + printf("Steam language is Czech\n"); + default_language = 3; + } */ + + string l = SteamApps()->GetCurrentGameLanguage(); + printf("Steam language: %s\n", l.c_str()); + if(l == "english") default_language = 0; + if(l == "polish") default_language = 1; + if(l == "turkish") default_language = 2; + if(l == "czech") default_language = 3; + if(l == "russian") default_language = 4; + + // SteamUserStats()->ClearAchievement("DIAMOND1"); + } + else { + printf("RequestStats - failed, %d\n", pCallback->m_eResult); + } + } + +void OnFindLeaderboard( LeaderboardFindResult_t *pFindLeaderboardResult, bool bIOFailure ) { + if ( !pFindLeaderboardResult->m_bLeaderboardFound || bIOFailure ) { + printf("Leaderboard not found!\n"); + return; + } + + // check to see which leaderboard handle we just retrieved + const char *pchName = SteamUserStats()->GetLeaderboardName( pFindLeaderboardResult->m_hSteamLeaderboard ); + + printf("Found leaderboard: '%s'\n", pchName); + + for(int i=0; im_hSteamLeaderboard; + + findLeaderboards(); + } + +void OnScoresDownloaded( LeaderboardScoresDownloaded_t *p, bool bIOFailure ) { + if ( bIOFailure ) { + printf("OnScoresDownloaded failure!\n"); + return; + } + + printf("Download count: %d\n", p->m_cEntryCount); + if(p->m_cEntryCount) { + LeaderboardEntry_t entry; + SteamUserStats()->GetDownloadedLeaderboardEntry( + p->m_hSteamLeaderboardEntries,0,&entry,NULL,0 + ); + + if(entry.m_steamIDUser == whoami) for(int i=0; im_hSteamLeaderboard == steamleader[i]) { + printf("Retrieved the current score for '%s': %d\n", leadernames[i], entry.m_nScore); + currentscore[i] = entry.m_nScore; + } + } + else { + for(int i=0; im_hSteamLeaderboard == steamleader[i]) + currentscore[i] = NO_SCORE_YET; + } + + findLeaderboards(); + } + +void achievement_init() { + if(SteamAPI_RestartAppIfNecessary(342610)) + exit(0); + if(SteamAPI_Init()) { + steam_appid = SteamUtils()->GetAppID(); + for(int i=0; iRequestCurrentStats()) { + printf("Request failed\n"); + } + + init_steamvisualinterface(OnUserStatsReceived, OnFindLeaderboard, OnScoresDownloaded); + findLeaderboards(); + } + else { + printf("Steam init failed\n"); + return; + } + } + +void achievement_gain(const char *name, bool euclideanAchievement) { + achievement_log(name, euclideanAchievement); + if(!steam_appid) return; + if(cheater) return; + if(euclid != euclideanAchievement) return; + + bool achieved; + SteamUserStats()->GetAchievement(name, &achieved); + SteamUserStats()->SetAchievement(name); + SteamUserStats()->StoreStats(); + + if(!achieved) { +// printf("NEW ACHIEVEMENT\n"); + achievementTimer = ticks; + achievementMessage[0] = XLAT("New Achievement:"); + achievementMessage[1] = SteamUserStats()->GetAchievementDisplayAttribute(name, "name"); + achievementMessage[2] = SteamUserStats()->GetAchievementDisplayAttribute(name, "desc"); + } + /* + for(int i=0; i 160) { + b++; v -= (v/3); + } + return 160+b; + } + +typedef unsigned char uchar; + +uchar ugc[640], qugc; + +void ugc_init() { + for(int x=0; x<640; x++) ugc[x] = 0; + qugc = 0; + } + +void ugc_char(uchar& x) { + ugc[qugc++] = x; + } + +void ugc_compress(int& x) { + ugc[qugc++] = i8(x); + } + +template void ugc_nocompress(T& x) { + uchar *z = (uchar*) &x; + for(int i=0; i<(int) sizeof(T); i++) ugc_char(z[i]); + } + +void upload_score(int id, int v) { + + if(!steam_appid) return; + if(!steamleader[id]) return; + + ugc_init(); + short vs; int vi; + vs = VERNUM_HEX; ugc_nocompress(vs); + vi = timerstart; ugc_nocompress(vi); + vi = countMyGolems(); ugc_compress(vi); + ugc_compress(turncount); + ugc_compress(cellcount); + ugc_compress(savecount); + uchar l = lastland; if(tampered) l |= 64; ugc_char(l); + vi = celldist(cwt.c); ugc_compress(vi); + vi = savetime + (timerstopped ? 0 : (time(NULL) - timerstart)); ugc_compress(vi); + for(int i=0; i<40; i++) ugc_compress(items[i]); + for(int i=0; i<67; i++) ugc_compress(kills[i]); + ugc_compress(explore[0]); ugc_compress(explore[5]); + for(int i=0; i<23; i++) ugc_compress(exploreland[0][i]); + + SteamUserStats()->UploadLeaderboardScore( steamleader[id], k_ELeaderboardUploadScoreMethodKeepBest, v, (int32*)&ugc, (qugc+3) / sizeof(int32)); + } + +bool haveLeaderboard(int id) { + return steamleader[id]; + } + +void achievement_close() { + if(!steam_appid) return; + SteamAPI_Shutdown(); + } + +void achievement_pump() { + SteamAPI_RunCallbacks(); + if(ticks > lastleader + 30000) + findLeaderboards(); + } + diff --git a/langen.cpp b/langen.cpp new file mode 100644 index 00000000..49c1cae2 --- /dev/null +++ b/langen.cpp @@ -0,0 +1,277 @@ +#define GEN_M 0 +#define GEN_F 1 +#define GEN_N 2 +#define GEN_O 3 + +using namespace std; +#include +#include +#include +#include +#include + +template int size(T x) { return x.size(); } + +#define NUMLAN 5 + +// language generator + +template struct dictionary { + map m; + void add(const string& s, const T& val) { m[s] = val; } + T& operator [] (const string& s) { return m[s]; } + int count(const string& s) { return m.count(s); } + void clear() { m.clear(); } + }; + +dictionary d[NUMLAN]; + +struct noun { + int genus; + string nom, nomp, acc, abl; + }; + +dictionary nouns[NUMLAN]; + +#include + +void addutftoset(set& s, string& w) { + int i = 0; +//printf("%s\n", w.c_str()); + while(i < size(w)) { + + if(w[i] < 0) { + string z = w.substr(i, 2); +// printf("Insert: %s [%02x%02x]\n", z.c_str(), w[i], w[i+1]); + s.insert(w.substr(i, 2)); + i += 2; + } + else { + s.insert(w.substr(i, 1)); + i++; + } + } + } + +void addutftoset(set& s, noun& w) { + addutftoset(s, w.nom); + addutftoset(s, w.nomp); + addutftoset(s, w.acc); + addutftoset(s, w.abl); + } + +template +void addutftoset(set& s, dictionary& w) { + for(typename map::iterator it = w.m.begin(); it != w.m.end(); it++) + addutftoset(s, it->second); + } + +set allchars; + +void printletters(dictionary& la, dictionary& nounla, const char *lang) { + set s; + addutftoset(s, la); + addutftoset(s, nounla); + addutftoset(allchars, la); + addutftoset(allchars, nounla); +//printf("%s:", lang); +//for(set::iterator it = s.begin(); it != s.end(); it++) +// printf(" \"%s\",", it->c_str()); +//printf("\n"); + } + +typedef unsigned hashcode; + +hashcode hashval; + +hashcode hash(const string& s) { + hashcode r = 0; + for(int i=0; i buildHashTable(set& s) { + map res; + for(set::iterator it = s.begin(); it != s.end(); it++) + res[hash(*it)] = *it; + return res; + } + +const char *escape(string s, string dft) { + if(s == "") { + printf("/*MISSING*/ "); + s = dft; + } + static string t; + t = "\""; + for(int i=0; i nothe; +set plural; + +#ifdef CHECKALL +const char* allstr[] = { +#include "d" + }; +#endif + +int main() { + + nothe.insert("R'Lyeh"); + plural.insert("Crossroads"); + +#define S(a,b) d[1].add(a,b); +#define N(a,b,c,d,e,f) \ + {noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = f; nouns[1].add(a,n);} +#include "language-pl.cpp" +#undef N +#undef S + +#define S(a,b) d[2].add(a,b); +#define N5(a,b,c,d,e) \ + {noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = e; nouns[2].add(a,n);} +#define N(a,b,c,d,e,f) \ + {noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = f; nouns[2].add(a,n);} +#include "language-tr.cpp" +#undef N +#undef S + +#define S(a,b) d[3].add(a,b); +#define N(a,b,c,d,e,f) \ + {noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = f; nouns[3].add(a,n);} +#include "language-cz.cpp" +#undef N +#undef S + +#define S(a,b) d[4].add(a,b); +#define N(a,b,c,d,e,f) \ + {noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = f; nouns[4].add(a,n);} +#include "language-ru.cpp" +#undef N +#undef S + + // verify + set s; + for(int i=1; i::iterator it = d[i].m.begin(); it != d[i].m.end(); it++) + s.insert(it->first); + + for(set::iterator x=s.begin(); x != s.end(); x++) { + string mis = ""; + for(int i=1; i::iterator it = nouns[i].m.begin(); it != nouns[i].m.end(); it++) + s.insert(it->first); + + for(set::iterator x=s.begin(); x != s.end(); x++) { + string mis = ""; + for(int i=1; i::iterator it = d[i].m.begin(); it != d[i].m.end(); it++) + s.insert(it->first); + + int ca = sizeof(allstr) / sizeof(char*); + for(int i=0; i::iterator x=s.begin(); x != s.end(); x++) { + bool b = false; + for(int i=0; i vchars; +//printf("ALL:"); + for(set::iterator it = allchars.begin(); it != allchars.end(); it++) { +// printf(" \"%s\",", it->c_str()); + if(size(*it) == 2) { javastring += (*it); vchars.push_back(*it); c++; } + } + printf("// DO NOT EDIT -- this file is generated automatically with langen\n"); + printf("\n"); + printf("#define NUMEXTRA %d\n", c); + printf("const char* natchars[NUMEXTRA] = {"); + for(int i=0; i allsent; + for(map::iterator it = d[1].m.begin(); it != d[1].m.end(); it++) + allsent.insert(it->first); + + set allnouns; + for(map::iterator it = nouns[1].m.begin(); it != nouns[1].m.end(); it++) + allnouns.insert(it->first); + + map ms, mn; + + do { + hashval = rand(); + printf("// check hash: %x\n", hashval); + ms = buildHashTable(allsent); + mn = buildHashTable(allnouns); + } + while(size(ms) != size(allsent) || size(mn) != size(allnouns)); + + printf("hashcode hashval = 0x%x;\n\n", hashval); + + printf("sentence all_sentences[%d] = {\n", size(allsent)); + + for(map::iterator it = ms.begin(); it != ms.end(); it++) { + string s = it->second; + printf(" {0x%x, { // %s\n", it->first, escape(s, s)); + for(int i=1; i::iterator it = mn.begin(); it != mn.end(); it++) { + string s = it->second; + printf(" {0x%x, %d, { // \"%s\"\n", it->first, + (nothe.count(s) ? 1:0) + (plural.count(s) ? 2:0), + escape(s, s)); + + for(int i=1; i" + +S("Welcome to HyperRogue", "Vítej ve hře HyperRogue") +S(" for Android", " na Android") +S(" for iOS", " na iOS") +S("! (version %1)\n\n", "! (verze %1)\n\n") +S(" (press ESC for some hints about it).", " (stiskni ESC pro trochu nápovědy).") +S("Press 'c' for credits.", "Stiskni 'c' pro zobrazení autorů") +S("game design, programming, texts and graphics by Zeno Rogue \n\n", + "design, programování, texty a grafika: Zeno Rogue \n\n") +S("add credits for your translation here", "Český překlad: Marek Čtrnáct \n\n") +S(" (touch to activate)", " (aktivuj dotekem)") +S(" (expired)", " (vypršelo)") +S(" [%1 turns]", " [počet kol: %1]") +S(", you", ", ty") +S("0 = Klein model, 1 = Poincaré model", "0 = Kleinův model, 1 = Poincarého model") +S("you are looking through it!", "díváš se skrz něj!") +S("simply resize the window to change resolution", "rozlišení můžeš změnit prostou změnou velikosti okna") +S("[+] keep the window size, [-] use the screen resolution", "[+] zachovej rozměr okna, [-] použij rozlišení obrazovky") +S("+5 = center instantly, -5 = do not center the map", "+5 = okamžité vycentrování, -5 = žádné centrování") +S("press Space or Home to center on the PC", "na PC můžeš vycentrovat obraz stisknutím mezerníku nebo klávesy Home") +S("You need special glasses to view the game in 3D", "Abys moh%l0 hru sledovat ve 3D, potřebuješ speciální brýle") +//Would %thel0 still work here? +S("You can choose one of the several modes", "Můžeš si vybrat jeden z několika módů") +S("ASCII", "ASCII") +S("black", "černý") +S("plain", "obyčejný") +S("Escher", "escherovský") +S("items only", "pouze předměty") +S("items and monsters", "předměty i netvoři") +S("no axes", "bez os") +S("auto", "auto") +S("light", "lehký") +S("heavy", "těžký") +S("The axes help with keyboard movement", "Osy pomáhají při pohybu pomocí klávesnice") +S("Config file: %1", "Soubor s nastavením: %1") +S("joystick mode: automatic (release the joystick to move)", "mód joysticku: automatický (pohybuješ se uvolněním joysticku)") +S("joystick mode: manual (press a button to move)", "mód joysticku: ruční (pohybuješ se stiskem tlačítka)") +S("Reduce the framerate limit to conserve CPU energy", "Sniž fps, abys šetřil energii procesoru") +S("Press F1 or right click for help", "Pro vyvolání nápovědy stiskni F1 nebo klikni pravým tlačítkem myši") +S("No info about this...", "O tomhle nemám žádné informace...") +S("Press Enter or F10 to save", "Enter nebo F10: uložit hru") +S("Press Enter or F10 to quit", "Enter nebo F10: ukončit hru") +S("or 'r' or F5 to restart", "'r' nebo F5: začít znovu od začátku") +S("or 't' to see the top scores", "'t': tabulka nejvyšších skóre") +S("or another key to continue", "jakákoli jiná klávesa: pokračovat") +S("It is a shame to cheat!", "Cheatovat je hanba!") +//While the word "cheat" can be translated into Czech, it's tricky using it as countable noun, and the English-derived terms are well-known. +S("Showoff mode", "Předváděcí mód") +S("Quest status", "Stav úkolů") +S("GAME OVER", "KONEC HRY") +S("Your score: %1", "Tvé skóre: %1") +S("Enemies killed: %1", "Zabitých netvorů: %1") +S("Orbs of Yendor found: %1", "Nalezených Yendorských sfér: %1") +S("Collect 30 $$$ to access more worlds", "Další kraje zpřístupníš sesbíráním 30 $$$") +// S("Collect 60 $$$ to access R'Lyeh and Dry Forest", "R'Lyeh a Suchý hvozd zpřístupníš sesbíráním 60 $$$") +S("Collect at least 10 treasures in each of 9 types to access Hell", "Peklo zpřístupníš sesbíráním 10 pokladů od každého z 9 typů") +S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Yendorské sféry zpřístupníš sesbíráním nejméně 10 Čertových kvítek") +S("Hyperstone Quest: collect at least 10 %1 in %the2", "Hyperkamový úkol: sesbírej nejméně 10 pokladů %abl2") +S("Hyperstone Quest completed!", "Hyperkamový úkol splněn!") +S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Hledej Yendorské sféry v Pekle nebo na Křižovatce!") +S("Unlock the Orb of Yendor!", "Odemkni Yendorskou sféru!") +S("Defeat 100 enemies to access the Graveyard", "Hřbitov zpřístupníš poražením 100 nepřátel") +S("(press ESC during the game to review your quest)", "(své úkoly můžeš během hry zobrazit stiskem ESC)") +S("you have cheated %1 times", "počet cheatů: %1") +S("%1 turns (%2)", "počet kol: %1 (%2)") +S("last messages:", "poslední zprávy: ") +S("time elapsed", "čas") +S("date", "datum") +S("treasure collected", "získané poklady") +S("total kills", "celkový počet zabitých nepřátel") +S("turn count", "počet kol") +S("cells generated", "počet vygenerovaných políček") +S("t/left/right - change display, up/down - scroll, s - sort by", "t/doleva/doprava - změna zobrazení, nahoru/dolů - posunování, s - řazení") +S("kills", "zab") +S("time", "čas") +S("ver", "ver") +S("SORT", "ŘAZ") +S("PLAY", "HRA") +S("Your total wealth", "Tvé celkové bohatství") +S("treasure collected: %1", "pokladů získáno: %1") +S("objects found: %1", "předmětů nalezeno: %1") +S("orb power: %1", "moc sfér: %1") +S(" (click to drop)", " (polož kliknutím)") +S("You can also scroll to the desired location and then press 't'.", "Také můžeš posunout obraz do požadované lokace a stisknout 't'.") +S("Thus, it is potentially useful for extremely long games, which would eat all the memory on your system otherwise.\n", "To je tedy potenciálně užitečné pro extrémně dlouhé hry, které by jinak sežraly všechnu paměť tvého počítače.") +S("You can touch the Dead Orb in your inventory to drop it.", "Mrtvou sféru ve svém inventáři můžeš položit tím, že se jí dotkneš.") +S("This might be useful for Android devices with limited memory.", "To se může hodit na zařízeních Android s omezenou pamětí.") +S("You can press 'g' or click them in the list to drop a Dead Orb.", "Mrtvou svéru můžeš položit stiskem klávesy 'g' nebo tím, že na ni klikneš v seznamu.") +S("frames per second", "snímky za sekundu") +S("monsters killed: %1", "netvorů zabito: %1") +S("Drawing %1 (layer %2), F1 for help", "Kreslím %1 (vrstva %2), F1 - nápověda") +S("hepta floor", "hepta-podlaha") +S("hexa floor", "hexa-podlaha") +S("character", "postava") +S("ESC for menu/quest", "ESC - menu/úkoly") +S("vector graphics editor", "editor vektorové grafiky") +S("cheat mode", "cheat mód") +S("heptagonal game board", "sedmiúhelníková herní deska") +S("triangular game board", "Trojúhelníková herní deska") +S("HyperRogue game board", "herní deska HyperRogue") +S("first page [Space]", "první stránka [mezerník]") +S("exit configuration", "opustit nastavení") +S("Configuration:", "Nastavení:") +S("video resolution", "rozlišení") +S("fullscreen mode", "zobrazení na celou obrazovku") +S("animation speed", "rychlost animace") +S("dist from hyperboloid ctr", "vzdálenost od středu hyperboloidu") +S("scale factor", "měřítko") +S("wall display mode", "mód zobrazování zdí") +S("monster display mode", "mód zobrazování netvorů") +S("cross display mode", "mód zobrazování os") +S("background music volume", "hlasitost hudby") +S("OFF", "VYP") +S("ON", "ZAP") +S("distance between eyes", "vzdálenost očí od sebe") +S("framerate limit", "limit fps") +S("joystick mode", "mód joysticku") +S("automatic", "automatický") +S("manual", "ruční") +S("language", "jazyk") +S("EN", "CZ") +S("player character", "tvoje postava") +S("male", "muž") +S("female", "žena") +S("use Shift to decrease and Ctrl to fine tune ", "použij Shift ke zmenšení a Ctrl k jemnému") +S("(e.g. Shift+Ctrl+Z)", "ladění (například Shift+Ctrl+Z)") +S("the second page [Space]", "druhá stránka [mezerník]") +S("special features [Space]", "zvláštní možnosti [mezerník]") +S("exit configuration", "opustit nastavení") +S("see the help screen", "zobrazit obrazovku s nápovědou") +S("save the current config", "uložit současné nastavení") +S("(v) config", "(v) nast.") +S("Screenshot saved to %1", "Snímek obrazovky uložen do %1") +S("You need an Orb of Teleport to teleport.", "K teleportaci potřebuješ Sféru teleportace.") +S("Use arrow keys to choose the teleport location.", "Vyber cíl teleportace pomocí šipek.") +S("openGL mode enabled", "mód openGL zapnut") +S("openGL mode disabled", "mód openGL vypnut") +S("openGL & antialiasing mode", "openGL & antialiasing") +S("anti-aliasing enabled", "anti-aliasing zapnut") +S("anti-aliasing disabled", "anti-aliasing vypnut") +S("You activate your demonic powers!", "Aktivoval jsi svou démonickou moc!") + +// Steam achievement messages + +S("New Achievement:", "Nový achievement:") +S("Your total treasure has been recorded in the Steam Leaderboards.", "Tvůj celkový poklad byl zaznamenán na žebříčky na Steamu.") +S("Congratulations!", "Gratulujeme!") +S("You have improved your total high score and %1 specific high scores!", "Zlepši%l0 jsi své celkové nejvyšší skóre a %1 specifických nejvyšších skóre!") +S("You have improved your total and '%1' high score!", "Zlepši%l0 jsi své celkové nejvyšší skóre a své nejvyšší skóre v kategorii '%P1!'") +S("You have improved your total high score on Steam. Congratulations!", "Zlepši%l0 jsi své celkové nejvyšší skóre na Steamu. Gratulujeme!") +S("You have improved %1 of your specific high scores!", "Zlepši%l0 jsi %1 svých specifických nejvyšších skóre!") +S("You have improved your '%1' high score on Steam!", "Zlepši%l0 jsi své nejvyšší skóre na Steamu v kategorii '%P1'!") +S("You have collected 10 treasures of each type.", "Získa%l0 jsi 10 pokladů od každého typu.") +S("This is your first victory!", "Toto je tvé první vítězství!") +S("This has been recorded in the Steam Leaderboards.", "Bylo zaznamenáno na žebříčky Steamu.") +S("The faster you get here, the better you are!", "Čím rychleji se sem dostaneš, tím lepší jsi!") +S("You have improved both your real time and turn count. Congratulations!", "Zlepši%l0 jsi svůj reálný čas i svůj počet kol. Gratulujeme!") +S("You have used less real time than ever before. Congratulations!", "Spotřebova%l0 jsi méně reálného času než kdy předtím. Gratulujeme!") +S("You have used less turns than ever before. Congratulations!", "Spotřebova%l0 jsi méně kol než kdy předtím. Gratulujeme!") + +// help texts. These are separated into multiple lines just for convenience, +// you don't have to follow. + +S( + "You have been trapped in a strange, non-Euclidean world. Collect as much treasure as possible " + "before being caught by monsters. The more treasure you collect, the more " + "monsters come to hunt you, as long as you are in the same land type. The " + "Orbs of Yendor are the ultimate treasure; get at least one of them to win the game!", + + "Jsi uvězněn v podivném, neeukleidovském světě. Sesbírej co nejvíce pokladů, " + "než tě dostanou netvoři. Čím víc pokladů sebereš, tím víc netvorů po tobě půjde, " + "dokud budeš ve stejném typu kraje. Největším pokladem jsou Yendorské sféry: " + "získáš-li alespoň jednu z nich, vyhraješ hru!" + ) + +S( + "You can fight most monsters by moving into their location. " + "The monster could also kill you by moving into your location, but the game " + "automatically cancels all moves which result in that.\n\n", + + "Na většinu netvorů můžeš zaútočit tím, že se pohneš na jejich políčko. " + "Netvor může zabít tebe, pokud se pohne na tvé políčko, ale hra automaticky " + "zruší každý tah, který by vedl k takové situaci.\n\n") + +S( + "Usually, you move by touching somewhere on the map; you can also touch one " + "of the four buttons on the map corners to change this (to scroll the map " + "or get information about map objects). You can also touch the " + "numbers displayed to get their meanings.\n", + "Pohybuješ se obvykle tak, že se dotkneš nějakého místa na mapě; to můžeš změnit " + "tím, že se dotkneš jednoho ze čtyř tlačítek v rohu mapy (pokud chceš posunovat mapu " + "nebo získat informace o objektech na mapě). Také se můžeš dotknout zobrazených čísel, " + "abys zjistil jejich význam.\n") + +S("Move with mouse, num pad, qweadzxc, or hjklyubn. Wait by pressing 's' or '.'. Spin the world with arrows, PageUp/Down, and Home/Space. " + "To save the game you need an Orb of Safety. Press 'v' for config, ESC for the quest status and menu.\n\n", + "Pohybuješ se pomocí myši, numerické klávesnice, kláves qweadzxc nebo kláves hjklyubn. Klávesy 's' nebo '.' ti umožňují čekat na místě. " + "Šipky, klávesy PgUp/PgDn a Home nebo mezerník ti umožňují otáčet svět. Nastavení můžeš otevřít klávesou 'v', úkoly a menu klávesou ESC.\n\n") + +S("See more on the website: ", "Více informací najdeš na webové stránce: ") + +S("special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n", + "zvláštní poděkování následujícím lidem za hlášení chyb, žádosti o nové funkce, porty a další pomoc:\n\n%1\n\n") + +S( + "The total value of the treasure you have collected.\n\n" + "Every world type contains a specific type of treasure, worth 1 $$$; " + "your goal is to collect as much treasure as possible, but every treasure you find " + "causes more enemies to hunt you in its native land.\n\n" + "Orbs of Yendor are worth 50 $$$ each.\n\n", + + "Celková hodnota pokladů, které jsi sesbíral.\n\n" + "V každém typu kraje se nachází specifický typ pokladů, který má vždy cenu 1 $$$; " + "tvým cílem je sesbírat co nejvíce pokladů, ale každý poklad, který získáš, " + "způsobí, že tě v krajích příslušného typu bude pronásledovat více nepřátel.\n\n" + "Každá Yendorská sféra má cenu 50 $$$.\n\n") + +S( + "The higher the number, the smoother the animations in the game. " + "If you find that animations are not smooth enough, you can try " + "to change the options ", + "Čím vyšší číslo, tím hladší budou animace ve hře. Pokud se ti zdá, že animace " + "nejsou dostatečně hladké, můžeš zkusit změnit nastavení ") + +S("(Menu button) and select the ASCII mode, which runs much faster. " + "Depending on your device, turning the OpenGL mode on or off might " + "make it faster, slower, or cause glitches.", + "(tlačítko 'Menu') a zvolit ASCII mód, který je mnohem rychlejší. Zapnutí " + "či vypnutí módu OpenGL může, v závislosti na tvém zařízení, hru zrychlit, " + "zpomalit, nebo vyvolat grafické chyby." + ) + +S("(in the MENU). You can reduce the sight range, this should make " + "the animations smoother.", + "(v MENU). Můžeš snížit viditelnost - to by mělo vést k hladším animacím.") + +S("(press v) and change the wall/monster mode to ASCII, or change " + "the resolution.", + "(stiskni 'v') a změň mód zdí/netvorů na ASCII, nebo změň rozlišení.") + +S( + "In this mode you can draw your own player character and floors. " + "Mostly for the development purposes, but you can have fun too.\n\n" + "f - floor, p - player (repeat 'p' for layers)\n\n" + "n - new shape, u - copy the 'player body' shape\n\n" + "1-9 - rotational symmetries, 0 - toggle axial symmetry\n\n" + "point with mouse and: a - add point, m - move nearest point, d - delete nearest point, c - nearest point again, b - add after nearest\n\n" + "s - save in C++ format (but cannot be loaded yet without editing source)\n\n" + "z - zoom, o - Poincaré model\n", + + "V tomto módu můžeš nakreslit vlastní postavu a podlahu. " + "Slouží především pro vývoj hry, ale můžeš se s ním i pobavit.\n\n" + "f - podlaha, p - postava (opakovaným stiskem 'p' přepínáš mezi vrstvami)\n\n" + "n - nový tvar, u - zkopíruj tvar 'tělo postavy'\n\n" + "1-9 - rotační symetrie, 0 - zapnout/vypnout osovou symetrii\n\n" + "zamiř myší a: a - přidej bod, m - přesuň nejbližší bod, d - vymaž nejbližší bod, c - znovu nejbližší bod, b - přidej za nejbližším\n\n" + "s - ulož ve formátu C++ (bez editování zdroje však prozatím soubor nelze nahrát)\n\n" + "z - přiblížení/vzdálení, o - Poincarého model\n") + +S( + "These huge monsters normally live below the sand, but your movements have " + "disturbed them. They are too big to be slain with your " + "weapons, but you can defeat them by making them unable to move. " + "This also produces some Spice. They move two times slower than you.", + + "Tito obrovští netvoři normálně žijí pod pískem, ale tvé pohyby je vyrušily. Jsou " + "tak velcí, že je nemůžeš zabít svými zbraněmi, ale můžeš je porazit tím, že jim " + "znemožníš pohyb. Tím také vznikne nějaké Koření. Píseční červi se pohybují " + "dvakrát pomaleji než ty.") + +S("The tentacles of Cthulhu are like sandworms, but longer. " + "They also withdraw one cell at a time, instead of exploding instantly.", + "Cthulhuova chapadla jsou něco jako Píseční červi, ale delší. " + "Kromě toho neexplodují okamžitě, ale ustupují políčko za políčkem.") + +S( + "A huge plant growing in the Jungle. Each Ivy has many branches, " + "and one branch grows per each of your moves. Branches grow in a clockwise " + "order. The root itself is vulnerable.", + "Obrovská rostlina, která roste v Džungli. Každý Břečťan má mnoho " + "větví, a po každém tvém pohybu jedna z nich povyroste. Větve " + "rostou v pořadí po směru hodinových ručiček. Kořen " + "Břečťanu je také zranitelný.") + +S("The Alchemists produce magical potions from pools of blue and red slime. You " + "can go through these pools, but you cannot move from a blue pool to a red " + "pool, or vice versa. Pools containing items count as colorless, and " + "they change color to the PC's previous color when the item is picked up. " + "Slime beasts also have to keep to their own color, " + "but when they are killed, they explode, destroying items and changing " + "the color of the slime and slime beasts around them.", + "Alchymisté vytvářejí magické lektvary z kaluží modrého a červeného slizu. " + "Ty můžeš těmito kalužemi procházet, ale nemůžeš se pohnout z modré " + "kaluže do červené nebo obráceně. Kaluže s předměty se berou jako bezbarvé " + "a po sebrání předmětu změní barvu na tu, na které jste byl předtím. I Slizoví " + "netvoři se mohou pohybovat jen v kalužích své vlastní barvy, ale když zemřou, " + "vybuchnou, což zničí předměty v jejich blízkosti a změní barvu okolního slizu " + "a Slizových netvorů.") + +S( + "These creatures are slow, but very powerful... more powerful than you. " + "You need some more experience in demon fighting before you will be able to defeat them. " + "Even then, you will be able to slay this one, but more powerful demons will come...\n\n" + "Each 10 lesser demons you kill, you become powerful enough to kill all the greater " + "demons on the screen, effectively turning them into lesser demons.", + + "Tito tvorové jsou pomalí, ale velmi silní... silnější než ty. Abys je mohl porazit, " + "musíš mít větší zkušenosti v boji proti démonům. I pak budeš sice schopný zabít " + "tohoto Ďábla, ale přijdou ještě silnější...\n\n" + "Za každých 10 Čertů, které zabiješ, získáš dost síly na to, abys mohl zabít všechny " + "Ďábly na obrazovce -- v podstatě se promění v Čerty.") + +S("These creatures are slow, but they often appear in large numbers.", + "Tito tvorové jsou pomalí, ale často se objevují ve velkém počtu.") + +S("A big monster from the Living Caves. A dead Troll will be reunited " + "with the rocks, causing some walls to grow around its body.", + "Velký netvor z Živoucích jeskyní. Mrtvý Šutroll splyne se skálou a kolem " + "jeho těla se rozrostou zdi.") + +S("Huge, impassable walls which separate various lands.", + "Obrovské, neprostupné zdi, které oddělují různé kraje.") + +S( + "This cave contains walls which are somehow living. After each turn, each cell " + "counts the number of living wall and living floor cells around it, and if it is " + "currently of a different type than the majority of cells around it, it switches. " + "Items count as three floor cells, and dead Trolls count as five wall cells. " + "Some foreign monsters also count as floor or wall cells.\n", + "Zdi této jeskyně jsou, kdovíjak, živé. Po každém kole každé políčko spočítá " + "počet políček s živoucími zdmi a políček s živoucími podlahami kolem sebe " + "a pokud má jiný typ než většina jeho sousedů, změní se ze zdi na podlahu nebo " + "opačně. Předměty se počítají jako tři políčka podlahy, mrtví Šutrollové jako " + "pět políček zdí. Někteří cizí netvoři se také počítají jako podlaha nebo zeď.\n") + +S( + "This forest is quite dry. Beware the bushfires!\n" + "Trees catch fire on the next turn. The temperature of the grass cells " + "rises once per turn for each fire nearby, and becomes fire itself " + "when its temperature has risen 10 times.\n" + "You can also cut down the trees. Big trees take two turns to cut down.", + "Tento hvozd je velice suchý. Pozor na požáry!\n" + "Stromy začnou hořet jedno kolo poté, co se ocitnou v sousedství ohně. Teplota " + "políček s trávou vzrůstá každé kolo o 1 za každé sousední políčko s ohněm " + "a poté, co vzroste desetkrát, začne tráva hořet.\n" + "Stromy v Suchém hvozdu můžeš kácet. Pokácení velkých stromů trvá dvě kola.") + +S("A big and quite intelligent monster living in the Icy Land.", + "Velký a dosti inteligentní netvor, který žije v Ledovém kraji.") + +S( + "A nasty predator from the Icy Land. Contrary to other monsters, " + "it tracks its prey by their heat.", + "Ošklivý predátor z Ledového kraje. Na rozdíl od jiných netvorů " + "sleduje kořist pomocí tepla, které vydává.") + +S("Rangers take care of the magic mirrors in the Land of Mirrors. " + "They know that rogues like to break these mirrors... so " + "they will attack you!", + "Strážci se starají o kouzelná zrcadla v Kraji zrcadel. Vědí, že lupiči " + "jako ty rádi tato zrcadla rozbíjejí... a proto na tebe útočí!") + +S("A nasty creature native to the Living Caves. They don't like you " + "for some reason.", + "Hnusná potvora žijící v Živoucích jeskyních. Z nějakého důvodu " + "tě nemají rády.") + +S("A tribe of men native to the Desert. They have even tamed the huge Sandworms, who won't attack them.", + "Kmen domorodců z Pouště. Dokázali dokonce zkrotit i obrovské Písečné červy, kteří na ně neútočí.") + +S("This giant ape thinks that you are an enemy.", "Tato obrovská opice si myslí, že jsi její nepřítel.") + +S("A magical being which copies your movements.", "Magická bytost, které kopíruje tvé pohyby.") + +S("A magical being which copies your movements. " + "You feel that it would be much more useful in an Euclidean space.", + "Magická bytost, která kopíruje tvé pohyby. Máš pocit, že v eukleidovském prostoru by byla mnohem užitečnější.") + +S("You can summon these friendly constructs with a magical process.", + "Tyto přátelské konstrukty můžeš vyvolat pomocí magického procesu.") + +S("A majestic bird, who is able to fly very fast.", + "Majestátní pták, který dokáže velmi rychle létat.") + +S("A monster who is able to live inside the living cave wall.", + "Netvor, který dokáže žít ve zdech Živoucí jeskyně.") + +S("A typical Graveyard monster.", "Typický hřbitovní netvor.") + +S("A typical monster from the Graveyard, who moves through walls.\n\n" + "There are also wandering Ghosts. They will appear " + "if you do not explore any new places for a long time (about 100 turns). " + "They can appear anywhere in the game.", + "Typický hřbitovní netvor, který dokáže procházet zdmi.\n\n" + "Existují také bludní Duchové, kteří se objeví, pokud dlouho (přibližně 100 kol) neprozkoumáš žádné nové místo. Ti se mohou objevit kdekoli ve hře.") + +S("Necromancers can raise ghosts and zombies from fresh graves.", + "Nekromanceři dokážou probouzet duchy a zombie z čerstvých hrobů.") + +S("A creepy monster who follows you everywhere in the Graveyard.", + "Děsivý netvor, který tě sleduje po celém Hřbitově.") + +S("People worshipping Cthulhu. They are very dangerous.", + "Lidé uctívající Cthulhua. Jsou velmi nebezpeční.") + +S("People worshipping Cthulhu. This one is especially dangerous, " + "as he is armed with a weapon which launches fire from afar.", + "Lidé uctívající Cthulhua. Tenhle je zvlášť nebezpečný, protože " + "je vybavený zbraní, která dokáže metat oheň na dálku.") + +S("This dangerous predator has killed many people, and has been sent to Cocytus.", + "Tento nebezpečný predátor zabil spoustu lidí, a tak byl poslán do Cocytu.") + +S("This white dog is able to run all the time. It is the only creature " + "able to survive and breed in the Land of Eternal Motion.", + "Tento bílý pes dokáže neustále běžet. Je to jediný tvor, který dokáže přežít a rozmnožovat se v Kraji věčného pohybu.") + +S("Demons of Hell do not drown when they fall into the lake in Cocytus. " + "They turn into demonic sharks, enveloped in a cloud of steam.", + "Když pekelní démoni spadnou do jezera v Cocytu, neutopí se. Místo " + "toho se promění v Ďábelské žraloky zahalené v oblaku páry.") + +S("These fairies would rather burn the forest, than let you get some Fern Flowers. " + "The forest is infinite, after all...\n\n" + "Fire Fairies transform into fires when they die.", + "Tito mužíčkové by raději spálili celý hvozd, než aby tě nechali sebrat nějaké " + "Kapradinové květy. Konečně, hvozd je přece nekonečný...\n\n" + "Ohniví mužíčkové se promění v oheň, když zemřou.") + +S("These warriors of the Forest wield exotic weapons called hedgehog blades. " + "These blades protect them from a frontal attack, but they still can be 'stabbed' " + "easily by moving from one place next to them to another.", + "Tito válečníci z Hvozdu vládnou exotickými zbraněmi zvanými 'ježčí čepele'. " + "Tyto čepele je chrání proti útoku zepředu, ale můžeš je snadno 'probodnout' tím, " + "že se pohneš z jednoho políčka, které s nimi sousedí, na druhé.") + +S("This being radiates an aura of wisdom. " + "It is made of a beautiful crystal, you would love to take it home. " + "But how is it going to defend itself? Better not to think of it, " + "thinking causes your brain to go hot...\n\n" + "Crystal Sages melt at -30 °C, and they can rise the temperature around you from afar.", + "Tato bytost vyzařuje auru moudrosti. Je vytvořená z krásného krystalu -- " + "moc rád%d0 by sis ji vza%l0 domů. Ale jak se bude bránit? Raději na to " + "nemyslet, z myšlení se ti zahřívá mozek...\n\n" + "Křišťáloví mudrci tají při teplotě -30 °C a dokážou kolem tebe na dálku " + "zvyšovat teplotu.") + +S("Cold white gems, found in the Icy Land.", "Chladné bílé drahokamy, které se nacházejí v Ledovém kraji.") + +S("An expensive metal from the Living Caves. For some reason " + "gold prevents the living walls from growing close to it.", + "Valouny drahého kovu z Živoucí jeskyně. Zlato z nějakého důvodu " + "zamezuje tomu, aby v jeho blízkosti rostly živoucí zdi.") + +S("A rare and expensive substance found in the Desert. " + "It is believed to extend life and raise special psychic powers.", + "Drahá a vzácná látka, která se nachází v Poušti. Věří se, že prodlužuje život a zlepšuje zvláštní psychické schopnosti.") + +S("A beautiful gem from the Jungle.", "Nádherný drahokam z Džungle.") + +S( + "A wonderful beverage, apparently obtained by mixing red and blue slime. You definitely feel more " + "healthy after drinking it, but you still fell that one hit of a monster is enough to kill you.", + "Úžasný nápoj, prý vytvořený smísením červeného a modrého slizu. Po jeho vypití se " + "rozhodně cítíš zdravější, ale pořád máš pocit, že by tě dokázal zabít jediný úder netvora.") + +S("A piece of a magic mirror, or a mirage cloud, that can be used for magical purposes. Only mirrors and clouds " + "in the Land of Mirrors leave these.", + "Kousek kouzelného zrcadla nebo oblaku přeludů, který je možné používat pro magické účely." + "Zanechávají je po sobě pouze zrcadla a oblaky v Kraji zrcadel.") + +S("These sinister totems contain valuable gems.", + "Tyto zlověstné totemy obsahují cenné drahokamy.") + +S("These star-shaped flowers native to Hell are a valuable alchemical component.", + "Tyto hvězdám podobné květiny z Pekla jsou cennou alchymistickou surovinou.") + +S("This statue is made of materials which cannot be found in your world.", + "Tato soška je vytvořena z materiálů, které se ve tvém světě nenacházejí.") + +S("One of few things that does not cause the floor in the Land of Eternal Motion to collapse. Obviously they are quite valuable.", + "Jedna z mála věcí, pod kterou se v Kraji věčného pohybu nepropadá země. Tato pírka jsou samozřejmě velice cenná.") + +S("Cold blue gems, found in the Cocytus.", "Chladné modré drahokamy, které se nacházejí v Cocytu.") + +S("These bright yellow gems can be found only by those who have mastered the Crossroads.", + "Tyto jasně žluté drahokamy mohou najít pouze ti, kdo ovládli celou Křižovatku.") + +S("That's all you need to unlock the Orb of Yendor! Well... as long as you are able to return to the Orb that this key unlocks...\n\n" + "Each key unlocks only the Orb of Yendor which led you to it.", + "To je všechno, co potřebuješ k odemčení Yendorské sféry! No... pokud se tedy dokážeš vrátit ke sféře, kterou tenhle klíč odemyká...\n" + "Každý klíč odemyká pouze tu Yendorskou sféru, která tě k němu zavedla.") + +S("These orbs can be found in the Graveyard. You think that they were once powerful magical orbs, but by now, their " + "power is long gone. No way to use them, you could as well simply drop them...\n\n", + "Tyto sféry můžeš najít na Hřbitově. Máš dojem, že to kdysi byly mocné magické sféry, " + "ale jejich moc už je dávno pryč. Nedají se nijak použít, můžeš je rovnou zase položit...\n\n") + +S( + "This wonderful Orb can only be collected by those who have truly mastered this hyperbolic universe, " + "as you need the right key to unlock it. Luckily, your psychic abilities will let you know " + "where the key is after you touch the Orb.", + "Tuto úžasnou sféru mohou sebrat jenom ti, kdo se stali skutečnými pány tohoto " + "hyperbolického vesníru, protože na její odemčení potřebuješ správný klíč. Tvé " + "psychické schopnosti ti naštěstí prozradí, kde se klíč nachází, jakmile se této sféry dotkneš.") + +S( + "This orb can be used to invoke the lightning spell, which causes lightning bolts to shoot from you in all directions.", + "Tuto sféru můžeš použít k seslání kouzla Blesk, které způsobí, že z tebe do všech směrů vyletí blesky.") + +S("This orb can be used to invoke a flash spell, which destroys almost everything in radius of 2.", + "Tuto sféru můžeš použít k seslání kouzla Záblesk, které zničí téměř vše do vzdálenosti 2 políček od tebe.") + +S("This orb can be used to invoke a wall of ice. It also protects you from fires.", + "Tuto sféru můžeš použít k vytvoření ledové zdi. Kromě toho tě chrání před ohněm.") + +S("This orb can be used to move faster for some time.", + "Tato sféra ti umožňuje pohybovat se po určitou dobu rychleji.") + +S("This orb can be used to summon friendly golems. It is used instantly when you pick it up.", + "Tuto sféru můžeš použít k vyvolání přátelských golemů. Použije se automaticky, jakmile ji sebereš.") + +S("This orb can protect you from damage.", "Tato sféra tě dokáže chránit před zraněním.") + +//S("This orb lets you go through the living wall. Only works in the Living Caves.", +// "Tato sféra ti umožňuje procházet živoucími zdmi. Funguje pouze v Živoucí jeskyni.") + +S("This orb lets you instantly move to another location on the map. Just click a location which " + "is not next to you to teleport there. ", + "Tato sféra ti umožňuje se okamžitě přemístit na jiné místo na mapě. Stačí, abys " + "klikl na libovolné nesousední políčko.") + +S("This orb lets you instantly move to a safe faraway location. Knowing the nature of this strange world, you doubt " + "that you will ever find the way back...\n\n" + "Your game will be saved if you quit the game while the Orb of Safety is still powered.\n\n" + "Technical note: as it is virtually impossible to return, this Orb recycles memory used for the world so far (even if you do not use it to save the game). ", + "Tato sféra ti umožňuje se okamžitě přemístit na bezpečné, vzdálené místo. Vzhledem " + "k povaze tohoto podivného světa pochybuješ, že ještě někdy najdeš cestu zpátky...\n\n" + "Pokud před vypršením efektu Sféry bezpečnosti ukončíš hru, uloží se.\n\n" + "Technická poznámka: vzhledem k tomu, že návrat do jakéhokoli již navštíveného místa je stejně prakticky nemožný, použití Sféry bezpečnosti uvolní veškerou paměť, kterou herní svět až dosud využíval, a to i tehdy, pokud ji nepoužiješ k uložení hry.") + +S("This orb allows attacking Hedgehog Warriors directly, as well as stabbing other monsters.\n", + "Tato sféra umožňuje útočit na Ježčí válečníky přímo a probodávat i jiné netvory.\n") + +S("This flower brings fortune to the person who finds it.\n", + "Tato rostlina přináší štěstí tomu, kdo ji najde.\n") + +S("Ice Walls melt after some time has passed.", "Ledové zdi časem tají.") + +S("A natural terrain feature of the Desert.", "Přírodní terénní prvek v Poušti.") + +S("You can go inside the Magic Mirror, and produce some mirror images to help you.", + "Do Kouzelného zrcadla můžeš vstoupit a vytvořit několik zrcadlových obrazů, které ti pomohou.") + +S( + "Tiny droplets of magical water. You see images of yourself inside them. " + "Go inside the cloud, to make these images help you.", + "Maličké kapičky magické vody. Vidíš v nich své obrazy. Když vejdeš do " + "oblaku, tyto obrazy ti pomohou.") + +S("A device that attracts sandworms and other enemies. You need to activate it.", + "Zařízení, které přitahuje písečné červy a jiné nepřátele. Aby začalo pracovat, musíš ho aktivovat.") + +S("A heap of wood that can be used to start a fire. Everything is already here, you just need to touch it to fire it.", + "Hromada dřeva, která se dá použít k zapálení ohně. Všechno už tu je, na podpálení se jí stačí jen dotknout.") + +S("An ancient grave.", "Starý hrob.") + +S("A fresh grave. Necromancers like those.", "Čerstvý hrob. Ty mají rádi nekromanceři.") + +S("A piece of architecture typical to R'Lyeh.", "Typický architektonický prvek R'Lyeh.") + +S("An impassable lake in Cocytus.", "Neprostupné jezero v Cocytu.") + +S("You can walk on it... but beware.", "Můžeš po něm chodit... ale pozor.") + +S("It was a floor... until something walked on it.", "Tady byla podlaha... než po ní něco přešlo.") + +S( + "This land is a quick gateway to other lands. It is very easy to find other lands " + "from the Crossroads. Which means that you find monsters from most other lands here!\n\n" + "As long as you have found enough treasure in their native lands, you can " + "find magical items in the Crossroads. Mirror Land brings mirrors and clouds, " + "and other land types bring magical orbs.\n\n" + "A special treasure, Hyperstone, can be found on the Crossroads, but only " + "after you have found 10 of every other treasure.", + "Tento kraj je rychlou branou do jiných krajů. Na Křižovatce je velmi snadné najít jiné " + "kraje. Což znamená, že tu najdeš i netvory z většiny jiných krajů!\n\n" + "Na Křižovatce můžeš najít magické předměty, pokud jsi v jejich krajích nalez%l0 dost " + "pokladů. Můžeš tu najít zrcadla a oblaky z Kraje zrcadel a magické sféry z jiných typů " + "krajů.\n\n" + "Na Křižovatce můžeš najít zvláštní poklad -- Hyperkam -- ale pouze poté, co najdeš " + "10 kusů od všech ostatních pokladů.") + +S("A hot land, full of sand dunes, mysterious Spice, and huge and dangerous sand worms.", + "Horký kraj plný písečných dun, tajemného Koření a obrovských a nebezpečných Písečných červů.") + +S( + "A very cold land, full of ice walls. Your mere presence will cause these ice walls to " + "melt, even if you don't want it.", + "Velmi chladný kraj plný ledových zdí. Tyto ledové zdi tají už tvou pouhou přítomností, ať už si to přeješ nebo ne.") + +S("A land filled with huge ivy plants and dangerous animals.", + "Kraj plný obrovských rostlin břečťanu a nebezpečných zvířat.") + +S("A strange land which contains mirrors and mirages, protected by Mirror Rangers.", + "Podivný kraj se zrcadly a přeludy, který chrání Zrcadloví strážci.") + +S("All the monsters you kill are carried to this strange land, and buried. " + "Careless Rogues are also carried here...", + "Všichni netvoři, které zabiješ, jsou odneseni do tohoto podivného kraje, " + "a tam pohřbeni. A také neopatrní lupiči...") + +S("An ancient sunken city which can be reached only when the stars are right.\n\n" + "You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Prastaré potopené město, kam se lze dostat pouze při správném postavení hvězd.\n\n" + "Po znalezieniu 5 Statuetek Cthulhu możesz w R'Lyeh trafić na Świątynie Cthulhu.") + +S("A land filled with demons and molten sulphur. Abandon all hope ye who enter here!", + "Kraj plný démonů a roztavené síry. Zanech vší naděje, ty, kdož vstupuješ!") + +S("This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.", + "Toto zamrzlé jezero je pekelnou verzí Ledového kraje. Tady tvým tělesným teplem netají zdi, ale podlaha.") + +S("A land where you cannot stop, because every piece of floor is extremely unstable. Only monsters who " + "can run forever are able to survive there, and only phoenix feathers are so light that they do not disturb " + "the floor.\n", + "Kraj, ve kterém se nemůžeš zastavit, protože každý kousek podlahy je nesmírně nestabilní. " + "Mohou tu přežít pouze netvoři, kteří dokážou věčně běžet, a pouze fénixova pírka jsou tak lehká, že nenaruší podlahu.") + +S("Affects looks and grammar", "Ovlivňuje vzhled a gramatiku") + +S("first joystick: movement threshold", "joystick 1: práh pohybu") +S("first joystick: execute movement threshold", "joystick 1: práh provedení pohybu") +S("second joystick: pan threshold", "joystick 2: práh posuvu") +S("second joystick: panning speed", "joystick 2: rychlost posouvání") +S("%The1 is frozen!", "%1 zamrz%l1!") +S("%The1 burns!", "%1 shoře%l1!") +S("message flash time", "doba blikání zprávy") + +S("skin color", "barva pleti") +S("weapon color", "barva zbraně") +S("hair color", "barva vlasů") +S("dress color", "barva šatů") +S("Shift=random, Ctrl=mix", "Shift=náhodná, Ctrl=směs") + +S("Euclidean mode", "Eukleidovský mód") +S("Return to the hyperbolic world", "Návrat do hyperbolického světa") +S("Choose from the lands visited this game.", "Vyber si z krajů, které jsi v této hře navštívil.") +S("Scores and achievements are not", "V Eukleidovském módu se"); +S("saved in the Euclidean mode!", "neukládají skóre a achievementy!"); + +S("MOVE", "POHYB") +S("BACK", "ZPĚT") +S("DRAG", "TAŽENÍ") +S("INFO", "INFORMACE") +S("MENU", "MENU") +S("QUEST", "ÚKOLY") +S("HELP", "NÁPOVĚDA") +S("NEW", "NOVÁ HRA") +S("PLAY", "HRAJ") +S("SHARE", "SDÍLEJ") +S("HyperRogue for Android", "HyperRogue pro Android") +S("Date: %1 time: %2 s ", "Datum: %1 čas: %2 s ") +S("distance: %1\n", "vzdálenost: %1\n") +S("Cheats: ", "Cheaty: ") +S("Score: ", "Skóre: ") +S("Kills: ", "Zabitých netvorů: ") +S("Retrieving scores from Google Leaderboards...", "Stahuji skóre z žebříčků Google...") +S("Scores retrieved.", "Skóre stažena.") + +S("Your total treasure has been recorded in the Google Leaderboards.", "Tvůj celkový poklad byl zaznamenán na žebříčky na Googleu.") +S("You have improved your total high score on Google. Congratulations!", "Zlepši%l0 jsi své celkové nejvyšší skóre na Googleu. Gratulujeme!") +S("You have improved your '%1' high score on Google!", "Zlepši%l0 jsi své nejvyšší skóre na Googleu v kategorii '%P1'!") +S("This has been recorded in the Google Leaderboards.", "Bylo zaznamenáno na žebříčky Googleu.") + +S("Ever wondered how some boardgame would look on the hyperbolic plane? " + "I wondered about Go, so I have created this feature. Now you can try yourself!\n" + "Enter = pick up an item (and score), space = clear an item\n" + "Other keys place orbs and terrain features of various kinds\n" + "In the periodic editor, press 0-4 to switch walls in different ways\n", + "Přemýšle%l0 jsi někdy o tom, jak by vypadala desková hra na hyperbolické rovině? " + "Mě zajímalo Go, a tak jsem vytvořil tuhle funkci. Teď si to můžeš vyzkoušet i ty!\n" + "Enter = seber předmět (a skóre), mezerník = vymaž předmět\n" + "Další klávesy umísťují sféry a nejrůznější terénní prvky\n" + "Stiskem kláves 0-4 můžete různě přepínat zdi\n") + +S("Periodic Editor", "Periodický editor") +// also translate this line: +// "Stiskem kláves 0-4 můžete různě přepínat zdi\n", + +S("Collect 60 $$$ to access even more lands", "Sesbíráním 60 $$$ získáš přístup do dalších krajů") + +// Emerald Mine + +N("Emerald Mine", GEN_O, "Smaragdový důl", "Smaragdové doly", "Smaragdový důl", "ve Smaragdovém dole") +N("Pikeman", GEN_M, "Kopiník", "Kopiníci", "Kopiníka", "Kopiníkem") +N("Flail Guard", GEN_M, "Strážce s řemdihem", "Strážci s řemdihy", "Strážce s řemdihem", "Strážcem s řemdihem") +N("Miner", GEN_M, "Horník", "Horníci", "Horníka", "Horníkem") +N("Emerald", GEN_O, "Smaragd", "Smaragdy", "Smaragd", "Smaragdem") + +Orb("the Mind", "Mysli") + +S( + "Evil people are mining for emeralds in this living cave. " + "It does not grow naturally, but it is dug out in a regular " + "pattern, which is optimal according to the evil engineers.", + "V této živoucí jeskyni těží zlí lidé smaragdy. " + "Neroste přirozeně, ale je vykopána v pravidelném vzoru, " + "který zlí inženýři pokládají za optimální.") + +S( + "Miners have special tools for dealing with the Living Cave. " + "When they die, these tools activate, destroying the living cave " + "around them.", + "Horníci mají speciální nástroje pro práci v Živoucí jeskyni. " + "Když zemřou, jejich nástroje se aktivují a zničí živoucí " + "jeskyni kolem nich.") + +S( + "When Pikemen move, they attack all cells which are now adjacent to them. " + "Luckily, they can be killed in the same way.\n\n" + "They never move if this would attack their friends.", + "Kopiníci po každém svém pohybu zaútočí na všechna okolní políčka " + "Naštěstí se dají zabít stejným způsobem.\n\n" + "Kopiníci se nepohnou, pokud by to znamenalo, že zaútočí na své přátele.") + +S( + "This guard of the Emerald Mine is wielding a huge flail. " + "You cannot attack him directly, as the flail would still hit you then. " + "Luckily, you have learned a trick: if you step away from him, " + "he will hit himself with the flail!", + + "Tento strážce Smaragdového dolu je vyzbrojen obrovským řemdihem. " + "Nemůžeš na něj útočit přímo, protože by tě řemdih i tak zasáhl. " + "Naštěstí ses naučil jeden trik: pokud se pohneš směrem od něj, " + "zasáhne řemdihem sám sebe!") + +S("A precious green gem from the Emerald Mines.", "Cenný zelený drahokam ze Smaragdového dolu.") + +S("%The1 pierces %the2!", "%1 probod%l1 %a2!") + +S("Make him hit himself by walking away from him.", + "Když se pohneš směrem od něj, zasáhne sám sebe.") + +S("This orb allows you to instantly kill a non-adjacent enemy by clicking it. " + "Each use drains 30 charges.", + "Tato sféra ti umožňuje zabít kliknutím libovolného nepřítele, který není na " + "sousedním políčku. Každé použití sníží náboj sféry o 30.") + +S("%The1 is immune to mental blasts!", "%1 je imunní proti mentálnímu útoku!") +S("You kill %the1 with a mental blast!", "Zabi%l1 jsi %a2 mentálním útokem!") + +// Vineyard + +N("Vineyard", GEN_F, "Vinice", "Vinice", "Vinici", "na Vinici") +N("Vine Beast", GEN_M, "Révový netvor", "Révoví netvoři", "Révového netvora", "Révovým netvorem") +N("Vine Spirit", GEN_M, "Révový duch", "Révoví duchové", "Révového ducha", "Révovým duchem") +N("vine", GEN_F, "réva", "réva", "révu", "révou") +N("partial fire", GEN_M, "částečný oheň", "částečné ohně", "částečný oheň", "částečným ohněm") +N("Wine", GEN_N, "Láhev vína", "Lahve vína", "Láhev vína", "Lahví vína") + +S( "This cell is partially on fire.", "Toto políčko částečně hoří.") + +S( + "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n" + "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.", + "Vinice je plná révy. Je tu velmi hustý vzor rovných čar...\n\n" + "Révoví netvoři a Révoví duchové mění políčka s révou na trávu a obráceně.") + +S("A vine is growing here... but only on a half of the cell. How is that even possible?!" + "Most monsters cannot move from this cell to the cell containing the other half. " + "Vine spirits can move only to the adjacent cells which are also adjacent to the " + "other half.", + "Tady roste réva... ale pouze na půlce políčka. Jak je to vůbec možné?!" + "Většina netvorů nemůže přecházet z tohoto políčka na políčko s druhou polovinou révy. " + "Révoví duchové se mohou pohybovat pouze na ta sousední políčka, která sousedí " + "i s druhou polovinou.") + +S( + "A beast made of vines!\n\n" + "Vine Beasts turn into vines when they die.", + "Netvor vytvořený z révy!\n\n" + "Révoví netvoři se po smrti promění v révu.") + +S( "A spirit living in the vines!\n\n" + "Vine Spirits destroy the vines when they die.", + "Duch žijící v révě!\n\n" + "Révoví duchové ničí révu, v níž se nacházejí, když zemřou.") + +S("Wine grown under hyperbolic sun would be extremely prized in your home location.", + "Víno vypěstované pod hyperbolickým sluncem by mělo ve tvé domovině velkou cenu.") + +S("This orb allows one to pass through all kinds of walls and chasms.", + "Tato sféra ti umožňuje procházet skrz libovolné zdi a přes propasti.") + +S("You cannot attack through the Vine!", + "Nemůžeš útočit skrz révu!") + +Orb("Aether", "Éteru") + +// Dead Caves + +N("Dead Cave", GEN_F, "Mrtvá jeskyně", "Mrtvé jeskyně", "Mrtvou jeskyni", "v Mrtvé jeskyni") +N("Dark Troll", GEN_M, "Temný troll", "Temní trollové", "Temného trolla", "Temným trollem") +N("Earth Elemental", GEN_M, "Elementál Země", "Elementálové Země", "Elementála Země", "Elementálem Země") +N("dead wall", GEN_F, "mrtvá zeď", "mrtvé zdi", "mrtvou zeď", "mrtvou zdí") +N("dead floor", GEN_F, "mrtvá podlaha", "mrtvé podlahy", "mrtvou podlahu", "mrtvou podlahou") +N("rubble", GEN_F, "sutiny", "sutiny", "sutiny", "sutinami") +N("Silver", GEN_N, "Kus stříbra", "Kusy stříbra", "Kus stříbra", "Kusem stříbra") + +S("A precious metal from the Dead Caves.", "Vzácný kov z Mrtvé jeskyně.") + +S( "A Troll without the power of Life.", "Troll bez síly Života.") + +S( + "A rare unliving construct from the Dead Caves. " + "It instantly destroys cave walls next to its path, and also leaves " + "an impassable wall behind it. You suppose that this impassable wall helps it to " + "escape from some threats. You hope you won't meet these threats...", + + "Vzácný neživý konstrukt z Mrtvých jeskyní. " + "Okamžitě ničí stěny jeskyně kolem své dráhy a zanechává " + "za sebou neprostupnou zeď. Tato neprostupná zeď mu zřejmě umožňuje uniknout " + "před nebezpečím. Doufáš, že na tato nebezpečí nenarazíš...") + +S("%The1 punches %the2!", "%1 udeři%l1 %a2!") +S("%The1 is destroyed by the forces of Life!", "Síla Života zničila %a1!") +S( "Somehow, this cave has not received the spark of Life yet.", + "Tato jeskyně z nějakého důvodu dosud nedostala jiskru Života.") + +// Hive +N("Hive", GEN_O, "Úl", "Úly", "Úl", "v Úlu") +N("Red Hyperbug", GEN_M, "Červený hyperhmyzák", "Červení hyperhmyzáci", "Červeného hyperhmyzáka", "Červeným hyperhmyzákem") +N("Green Hyperbug", GEN_M, "Zelený hyperhmyzák", "Zelení hyperhmyzáci", "Zeleného hyperhmyzáka", "Zeleným hyperhmyzákem") +N("Blue Hyperbug", GEN_M, "Modrý hyperhmyzák", "Modří hyperhmyzáci", "Modrého hyperhmyzáka", "Modrým hyperhmyzákem") +N("Royal Jelly", GEN_F, "Mateří kašička", "Mateří kašičky", "Mateří kašičku", "Mateří kašičkou") +N("weird rock", GEN_F, "podivná skála", "podivné skály", "podivnou skálu", "podivnou skálou") + +Orb("Invisibility", "Neviditelnosti") + +S("A weirdly colored rock. Hyperentomologists claim that the " + "Hyperbug armies use these rocks to navigate back home after a victorious battle.", + "Podivně zbarvená skála. Hyperentomologové tvrdí, že armády Hyperhmyzáků " + "je používají k navigaci, když se vracejí domů po vítězné bitvě.") + +S("%The1 fights with %the2!", "%1 se pustil do boje s %a2!") + +S("The Hive is filled with Hyperbugs. They are huge insects which look a bit like " + "ants, a bit like bees, and a bit like roaches. " + "They live in circular nests, and an army of Hyperbugs will attack any intruder, " + "including you and enemy Hyperbugs. Will you manage to get to the " + "heart of such a nest, and get the precious Royal Jelly?", + "Úl je plný Hyperhmyzáků. Tento obří hmyz vypadá trochu jako mravenci, " + "trochu jako včely a trochu jako švábi. Žijí v kruhových úlech a jejich armáda " + "zaútočí na každého vetřelce včetně tebe a nepřátelských Hyperhmyzáků. " + "Dokážeš se dostat do srdce takového kruhového úlu a získat vzácnou Mateří kašičku?") + +S("This is what Hyperbug Queens eat. Very tasty and healthy.", + "Tohle je potrava, kterou jedí Královny hyperhmyzáků. Velmi chutná a zdravá.") + +S("When you have this Orb, most monsters won't see you, unless " + "you are standing still, attacking, or picking up items.", + "Dokud máš tuto Sféru, většina netvorů tě neuvidí, pokud nebudeš " + "stát na místě, nezaútočíš nebo nesebereš předmět.") + +Orb("Earth", "Země") + +S("This orb lets you go through living walls. It also has powers in some of the other lands.", + "Tato sféra ti umožňuje procházet živoucími zdmi. Má také určité schopnosti v některých jiných krajích.") + +// Land of Power + +N("Land of Power", GEN_O, "Kraj Moci", "Kraje Moci", "Kraj Moci", "v Kraji Moci") +N("Witch Apprentice", GEN_F, "Učednice", "Učednice", "Učednici", "Učednicí") +N("Speed Witch", GEN_F, "Čarodějnice Rychlosti", "Čarodějnice Rychlosti", "Čarodějnici Rychlosti", "Čarodějnicí Rychlosti") +N("Flash Witch", GEN_F, "Čarodějnice Záblesku", "Čarodějnice Záblesku", "Čarodějnicí Záblesku", "Čarodějnicí Záblesku") +N("Fire Witch", GEN_F, "Čarodějnice Ohně", "Čarodějnice Ohně", "Čarodějnici Ohně", "Čarodějnicí Ohně") +N("Aether Witch", GEN_F, "Čarodějnice Éteru", "Čarodějnice Éteru", "Čarodějnici Éteru", "Čarodějnicí Éteru") +N("Winter Witch", GEN_F, "Čarodějnice Zimy", "Čarodějnice Zimy", "Čarodějnici Zimy", "Čarodějnicí Zimy") +N("Evil Golem", GEN_M, "Zlý golem", "Zlí golemové", "Zlého golema", "Zlým golemem") +N("Powerstone", GEN_O, "Mocikam", "Mocikamy", "Mocikam", "Mocikamem") +N("crystal cabinet", GEN_F, "křišťálová vitrína", "křišťálové vitríny", "křišťálovou vitrínu", "křišťálovou vitrínou") + +S("When you have this Orb, you will leave a trail of fire behind you.", + "Když máš tuto Sféru, zanecháváš za sebou ohnivou stopu.") + +S( + "A Witch without any special powers. But watch out! She will " + "pick up any basic Orbs on her path, and use their powers.", + "Čarodějnice bez jakýchkoli zvláštních schopností. Ale pozor! " + "Učednice sbírají jakékoli základní Sféry, na které narazí " + "a používají jejich schopnosti.") + +S( "A Witch with a Speed spell. She moves twice as fast as you. Unless you " + "have an Orb of Speed too, of course!", + "Čarodějnice s kouzlem Rychlosti. Pohybuje se dvakrát rychleji než ty. " + "Samozřejmě, pokud náhodou také nemáš Sféru Rychlosti!") + +/* S( "A Witch with a Flash spell. Very dangerous!\n\nLuckily, she never uses the spell if it " + "would kill her friends.", + "Čarodějnice s kouzlem Záblesk. Velmi nebezpečná, ale nepoužije své kouzlo, pokud by to zasáhlo její přátele.") */ + +S( "A Witch with a Fire spell. She will leave a trail of fire behind her.", + "Čarodějnice s kouzlem Ohně. Zanechává za sebou ohnivou stopu.") + +S( "A Witch with a Winter spell. She is able to move through fire.", + "Čarodějnice s kouzlem Zimy. Dokáže se pohybovat skrz oheň.") + +S( "A Witch with an Aether spell. She is able to move through fire and walls.", + "Čarodějnice s kouzlem Éteru. Dokáže procházet ohněm a zdmi.") + +S( "Somebody has summoned these evil constructs with a magical process.", + "Tyto zlé konstrukty kdosi vyvolal pomocí magického procesu.") + +S( "The Land of Power is filled with everburning fire, magical Orbs, and guarded by " + "witches and golems. There are basic orbs lying everywhere, and more prized ones " + "are kept in crystal cabinets.\n\n" + "Witches are allowed to use all the powers of the " + "basic orbs against intruders. These powers never expire, but a Witch " + "can use only one power at a time (not counting Orbs of Life).\n\n" + "Witches and Golems don't pursue you into other Lands. Also, most Orb powers" + "are drained when you leave the Land of Power.", + "Kraj Moci je plný věčně planoucích ohňů a magických Sfér a střeží ho " + "čarodějnice a golemové. Základní Sféry se válejí všude kolem a ty cennější " + "jsou schované v křišťálových vitrínách.\n\n" + "Čarodějnice mohou v boji proti vetřelcům používat všechny základní sféry. " + "Jejich síla se nikdy nevyčerpá, ale každá Čarodějnice může mít vždy pouze " + "jednu schopnost (Sféry Života se nepočítají).\n\n" + "Čarodějnice a golemové tě nikdy nebudou pronásledovat do jiných Krajů. " + "Kromě toho většina sfér při opuštění Kraje Moci svou sílu ztratí.") + +S( + "Witches use these crystal cabinets to protect Powerstones, as well as the more " + "expensive Orbs. They are partially protected from thieves: they are too strong " + "to be smashed by conventional attacks, and if you try to steal the item " + "using an Orb of Aether, your Aether power will be completely drained.", + "Čarodějnice používají tyto vitríny k ochraně Mocikamů, a také dražších " + "typů Sfér. Vitríny jsou částečně chráněné proti zlodějům: jsou příliš odolné na to, " + "aby se daly rozbít běžným útokem, a pokud se pokusíš předmět ukrást pomocí Sféry Éteru, " + "zcela to vyčerpá její sílu.") + +S( + "A Stone from the Land of Power. You are not sure what it is exactly, but " + "as the Powerstones are kept in crystal cabinets, they are surely valuable.", + "Kámen z Kraje Moci. Nejsi si jistý, co je přesně zač, ale když dávají " + "Mocikamy do křišťálových vitrín, musejí mít jistě velkou cenu.") + +Orb("Fire", "Ohně") + +// achievements: + +// "Head Witch", "Have 10 Orbs active at the same time." +// "Hlavní Čarodějnice", "Měj aktivních 10 Sfér najednou." + +// "Enemy Number One", "Have an army of 1000 hyperbugs pursue you." +// "Nepřítel číslo jedna", "Měj v patách armádu 1000 hyperhmyzáků." + +// "Lifebringer", "Brought Life into the Dead Caves." +// "Životabudič", "Přinesl jsi Život do Mrtvých jeskyní." + +// "Wall Gardener", "Make a living wall grow outside of a cavernous region." +// "Zedník a zahradník", "Vypěstuj živoucí zeď mimo jeskynní oblast." + +// "Master Swordsman", "Defeat a Hedgehog Warrior, a Pikeman, and a Flail Guard at the same time in melee." +// "Mistr meče", "Zabij Ježčího válečníka, Kopiníka a Strážce s řemdihem bez použití speciálních útoků." + +// "Master of Melee", "Defeat five monsters in melee at the same time." +// "Mistr boje nablízko", "Zabij pět netvorů naráz bez použití speciálních útoků." + +// for collection achievements: +// provide the required cases for descriptions: +// Emerald, Royal Jelly, Silver, Powerstone, and Wine +// achievement names: +// Master of the Hive, Master of Power, Master of Vineyard, Master of Dead Caves, Master of the Mine +// "Hyperbug", "Hyperbug Warrior", "Hyperbug Queen", + +// Pán Úlu, Pán Moci, Pán Vinice, Pán Mrtvých jeskyní, Pán dolu +// "Hyperhmyzák", "Hyperhmyzácký válečník", "Královna hyperhmyzáků", + +// for the store description: + +// (currently, five more lands are included!) +// (nyní s pěti dalšími Kraji!) + +S("Your Aether power has expired! RUN!", "Tvá síla Éteru vyprchala. UTÍKEJ!") + +S("%The1 tricks %the2.", "%1 přelsti%l1 %a2.") // this is for attacks against Pikemen and Flail Guards + +S("You trick %the1.", "Přelsti%l0 jsi %a1.") + +S( "A Witch with a Flash spell. Very dangerous!\n\nLuckily, she never uses the spell if it " + + "would kill her friends. She could destroy an Evil Golem, though.", + + "Čarodějnice s kouzlem Záblesk. Velmi nebezpečná!\n\nNaštěstí toto kouzlo nepoužije, " + + " pokud by to zabilo její přátele. Zlé golemy ale ničit může.") + +S("Your Aether powers are drained by %the1!", "%1 vysála tvou sílu Éteru!") + +// currently only crystal cabinets, so only female form + +S("As you leave, your powers are drained!", "Opouštíš Kraj Moci... Tvá síla mizí!") + +S("%The1 picks up %the2!", "%1 sebrala %a2!") // currently only Witches, so only female form + +S("You can right click any element to get more information about it.\n\n", + "Informace o jakémkoli herním prvku můžeš zobrazit tak, že na něj klikneš pravým tlačítkem myši.\n\n" +) + +S("TRANSLATIONWARNING", "") + +S("The Hyperbugs are fighting!", "Hyperhmyzáci bojují mezi sebou!") + +S("","") N("",GEN_N,"","","","") + +S("Cheat-changed the display.", "Cheat-changed the display.") +S("Dead floor, with some rubble.", "Mrtvá podlaha se sutinami.") + +// Camelot + +N("Camelot", GEN_O, "Camelot", "Cameloty", "Camelotu", "v Camelotu") +N("wall of Camelot", GEN_F, "hradba Camelotu", "hradby Camelotu", "hradbu Camelotu", "hradbou Camelotu") +N("moat of Camelot", GEN_O, "vodní příkop", "vodní příkopy", "vodní příkop", "vodním příkopem") +N("Round Table", GEN_O, "Kulatý stůl", "Kulaté stoly", "Kulatý stůl", "Kulatým stolem") +N("Knight", GEN_M, "Rytíř", "Rytíři", "Rytíře", "Rytířem") +N("Holy Grail", GEN_O, "Svatý grál", "Svaté grály", "Svatý grál", "Svatým grálem") + +S( + "The Knights of the Round Table are the greatest warriors of these lands. " + "They are not very inventive with names though, as they call each of their " + "castles Camelot. " + "You are probably worth of joining them, but they will surely give you " + "some quest to prove yourself...\n\n" + "Each castle contains a single treasure, the Holy Grail, in the center. " + "The radius of the Round Table is usually 28, but after you find a Holy Grail " + "successfully, each new castle (and each Round Table) you find will be bigger.", + + "Rytíři Kulatého stolu jsou největší bojovníci těchto krajů. Ale nemají zrovna " + "talent na vymýšlení jmen, protože všem svým hradům říkají Camelot. " + "Pravděpodobně jsi hoden toho, aby ses k nim připojil, ale " + "určitě budeš muset splnit nějaký úkol, abys jim to dokázal...\n\n" + "Na každém hradě je jeden poklad (Svatý grál), který se nachází v jeho středu. " + "Poloměr Kulatého stolu je obvykle 28, ale poté, co najdeš Svatý grál, bude " + "každý další hrad (a každý další Kulatý stůl) větší a větší.") + +S("It would be impolite to land on the table!", + "Přístát na stole by bylo nezdvořilé!") +S("You jump over the table!", "Přeskočil jsi stůl!") +S("That was not a challenge. Find a larger castle!", + "To nebylo nic těžkého. Najdi si větší hrad!") +S("The Knights congratulate you on your success!", + "Rytíři ti gratulují ke tvému úspěchu!") +S("The Knights laugh at your failure!", + "Rytíři se smějí tvému neúspěchu!") +S("The Knights stare at you!", "Rytíři na tebe zírají!") +S("Come on, this is too easy... find a bigger castle!", + "Ale no tak, tohle je příliš jednoduché... najdi si větší hrad!") +S("The Knights wish you luck!", "Rytíři ti přejí hodně štěstí!") + +S("\"I would like to congratulate you again!\"", "\"Rád bych ti znovu pogratuloval!\"") +S("\"Find the Holy Grail to become one of us!\"", "\"Najdi svatý grál a staneš se jedním z nás!\"") +S("\"The Holy Grail is in the center of the Round Table.\"", "\"Svatý grál je ve středu Kulatého stolu.\"") +S("\"I enjoy watching the hyperbug battles.\"", "\"Rád se dívám na bitvy Hyperhmyzáků.\"") +S("\"Have you visited a temple in R'Lyeh?\"", "\"Navštívi%l0 jsi už chrám v R'Lyeh?\"") +S("\"Nice castle, eh?\"", "\"Fajn hrad, co?\"") + +S("Congratulations! You have found the Holy Grail!", + "Gratulujeme! Naš%el0 jsi Svatý grál!") + +// Temple + +N("Temple of Cthulhu", GEN_O, "Cthulhuův chrám", "Cthulhuovy chrámy", "Cthulhuův chrám", "v Cthulhuově chrámu") +N("big statue of Cthulhu", GEN_F, "Cthulhuova socha", "Cthulhuovy sochy", "Cthulhuovu sochu", "Cthulhuovou sochou") +N("Grimoire", GEN_O, "Grimoár", "Grimoáry", "Grimoár", "Grimoárem") +N("Cult Leader", GEN_M, "Vůdce kultu", "Vůdcové kultu", "Vůdce kultu", "Vůdcem kultu") + +S("The temple of Cthulhu consists of many concentric circles of columns. " + "You will surely encounter many Cultists there, who believe that a pilgrimage " + "to the inner circles will bring them closer to Cthulhu himself, and Grimoires " + "which surely contain many interesting secrets.\n\n" + "The circles in the temple of Cthulhu are actually horocycles. They are " + "infinite, and there is an infinite number of them.", + + "Cthulhuův chrám sestává z mnoha soustředných kruhů sloupů. " + "Jistě tu narazíš na mnoho Kultistů, kteří věří, že je vykonání pouti do vnitřních kruhů " + "přivede blíž k samotnému Cthulhuovi a ke Grimoárům, které jistě obsahují " + "mnoho zajímavých tajemství.\n\n" + "Kruhy v Cthulhuově chtámu jsou ve skutečnosti horocykly. Jsou nekonečně velké " + "a je jich nekonečně mnoho." + ) + +S("The Grimoires contain many secrets of the Great Old Ones. " + "Each new inner circle in the Temple of Cthulhu contains new Grimoires, with new secrets. " + "You hope to read them when you return home, and to learn many things. " + "The knowledge is valuable to you, but it is rather pointless to try to get " + "several copies of the same Grimoire...", + "Grimoáry obsahují mnoho tajemství Starých Velkých. " + "Každý další vnitřní kruh Cthulhuova chrámu obsahuje nové Grimoáry s novými tajemstvími. " + "Doufáš, že si je všechny přečteš, až se vrátíš domů, a že se naučíš mnoho věcí. " + "Znalosti z Grimoárů jsou pro tebe cenné, ale nemá smysl snažit se získat několik kopií " + "stejného Grimoáru..." + ) + +S("These statues of Cthulhu are too large to carry, and they don't look too " + "valuable anyway. Most monsters will never go through them... they probably have " + "their reasons. But you can go! When you move into the cell containing " + "a statue, you push the statue to the cell you left.\n", + + "Tyto Cthulhuovy sochy jsou příliš velké na to, abys je unesl, a navíc ani nevypadají " + "příliš cenné. Většina netvorů skrz ně nikdy nepůjde... asi mají své důvody. Ale ty " + "přes ně chodit můžeš! Když vstoupíš na políčko se sochou, odstrčíš ji na to políčko, " + "které jsi opusti%l0." + ) + +S("These Cultists can push the statues, just like you.", + "Tito kultisté dokážou strkat sochy, stejně jako ty.") + +S("You already have this Grimoire! Seek new tomes in the inner circles.", + "Tenhle Grimoár už máš! Hledej nové Grimoáry ve vnitřních kruzích.") + +S("You push %the1 behind you!", "Odstrčil jsi %a1 za sebe.") + +// More texts + +S("Your total kills", "Celkový počet zabitých netvorů") + +S( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count.", + + "Ve většině krajů se objevuje tím víc pokladů, čím víc zabijete nepřátel, kteří v nich žijí. " + "Kromě toho musíš zabít 100 netvorů, aby ses mohl dostat na Hřbitov a do Úlu.\n\n" + "Přátelští tvorové a části netvorů (jako je Břečťan) se v seznamu objevují, ale " + "do celkového počtu zabitých netvorů se nepočítají.") + +S("There must be some temples of Cthulhu in R'Lyeh...", + "Cthulhu musí mít V R'Lyeh nějaké Chrámy...") + +S("You overheard Hedgehog Warriors talking about emeralds...", + "Zaslechl jsi Ježčí válečníky, jak mluví o smaragdech...") + +S("You overhear miners talking about a castle...", + "Zaslechl jsi Horníky, jak mluví o nějakém hradu...") + +S("A castle in the Crossroads...", "O hradu na Křižovatce...") + +//S("You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", +// "Po sebrání pěti Cthulhuových sošek můžeš v R'Lyeh najít Cthulhuovy chrámy.") + +S("You have to escape first!", "Nejprve musíš utéct!"); +S("There is not enough space!", "Není tady dost místa!"); + +S("Customize character", "upravit postavu") +S("gender", "pohlaví") + +Orb("the Dragon", "Draka") + +S("This Orb allows you to throw fire, just like the Fire Cultists.\n\n" + "Each fire drains 5 charges. You are not allowed to throw fire into adjacent cells.", + "Tato sféra ti umožňuje vrhat oheň jako Kultisté ohně.\n\n" + "Každé použití sníží náboj sféry o 5. Oheň nelze vrhnout na sousední políčko." + ) + +S("You throw fire!", "Vrhl jsi oheň!") + +Orb("Trickery", "Klamu") + +N("Illusion", GEN_F, "Iluze", "Iluze", "Iluzi", "Iluzí") + +S("This Orb allows you to create illusions of yourself. Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.\n\n" + "Each illusion takes 5 charges to create, and one extra charge " + "per turn. You can also click your illusion to take it away, restoring 4 charges.\n\n" + "If you have both Orb of Teleport and Orb of Trickery, Illusion is cast " + "first -- you can then teleport on your Illusion to switch places with it.", + "Tato sféra ti umožňuje vytvářet své iluzorní dvojníky. Většina netvorů půjde po tvých " + "iluzích, stejně jako jdou po tobě, po Tloucích a po tvých přátelích.\n\n" + "Stvoření každé iluze sníží náboj sféry o 5 a vyčerpává 1 náboj navíc za kolo. " + "Můžeš také kliknout na svou iluzi a zrušit ji, čímž se náboj sféry zvýší o 4.\n\n" + "Pokud máš Sféru Teleportace a Sféru Klamu zároveň, nejprve použiješ Sféru Klamu -- " + "poté se můžeš teleportovat na svou iluzi a vyměnit si s ní místo." + ) + +S("Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.", + "Většina netvorů půjde po tvých " + "iluzích, stejně jako jdou po tobě, po Tloucích a po tvých přátelích.") + +S("You create an Illusion!", "Vytvořil jsi iluzi!") +S("You take the Illusion away.", "Zrušil jsi iluzi.") + +#undef Orb + +S("Cannot teleport on a monster!", "Nemůžeš se teleportovat na netvora!") +S("Cannot teleport on an item!", "Nemůžeš se teleportovat na předmět!") +S("Cannot teleport here!", "Sem se teleportovat nemůžeš!") +//S("You cannot teleport that far away!", "Tak daleko se teleportovat nemůžeš!") + +S("You cannot target that far away!", "Nemůžeš zamířit tak daleko!") +S("You cannot target that close!", "Nemůžeš zamířit tak blízko!") +S("Cannot teleport on a monster!", "Nemůžeš se teleportovat na netvora!") +S("Cannot teleport on an item!", "Nemůžeš se teleportovat na předmět!") +S("Cannot teleport here!", "Sem se teleportovat nemůžeš!") +S("Cannot cast illusion on an item!", "Nemůžeš seslat iluzi na předmět!") +S("Cannot cast illusion here!", "Sem nemůžeš seslat iluzi!") +S("Cannot cast illusion on a monster!", "Nemůžeš seslat iluzi na netvora!") +S("Cannot throw fire there!", "Sem nemůžeš vrhnout oheň!") + +S("or ESC to see how it ended", "nebo ESC, abys vidě%l0, jak to skončilo") +S("high contrast", "vysoký kontrast") +S("draw the heptagons darker", "tmavší sedmiúhelníky"); +S("targetting ranged Orbs Shift+click only", + "zaměřování dálkových Sfér pouze kombinací Shift + kliknutí") +S("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.", + "Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, atd.") +S("also hold Alt during the game to toggle high contrast", + "Podržením klávesy Alt během hry lze přepnout vysoký kontrast") diff --git a/language-de.cpp b/language-de.cpp new file mode 100644 index 00000000..fb684b48 --- /dev/null +++ b/language-de.cpp @@ -0,0 +1,1480 @@ +// This translation file is encoded with UTF-8 + +// Nouns. + +// For each noun in English, provide: + +// 1) the type (usually gender) of the noun. For example, in Polish each noun can be: + +// masculine living (GEN_M), +// masculine object (GEN_O), +// feminine (GEN_F), or +// neuter (GEN_N). + +// 2) all the forms required by HyperRogue. For example, in Polish the following are +// given: +// The following forms are given: +// nominative (referred to as %1), +// nominative plural (%P1), +// accusative (%a1), +// ablative (%abl1) (for land names, locative "in/on..." is given instead of ablative). + +// Feel free to add more or less forms or types if needed. Note that you don't +// have to provide all the forms in your language, only those used by HyperRogue +// (in Polish just 4 of 14 forms are used, and this is probably similar in other +// languages). + +// monsters +N("Icewolf", GEN_M, "Eiswolf", "Eiswölfe", "Eiswolf", "Eiswolf") +N("Ranger", GEN_M, "Wildhüter", "Wildhüter", "Wildhüter", "Wildhüter") +N("Rock Troll", GEN_M, "Höhlentroll", "Höhlentrolle", "Höhlentroll", "Höhlentroll") +N("Goblin", GEN_M, "Höhlen Kobold", "Höhlen Kobolde", "Höhlen Kobold", "Höhlen Kobold") +N("Sand Worm", GEN_M, "Sand-Wurm-Kopf", "Sand-Wurm-Köpfe", "Sand-Wurm-Kopf", "Sand-Wurm-Kopf") +N("Sand Worm Tail", GEN_M, "Sand-Wurm-Schwanz", "Sand-Wurm-Schwänze", "Sand-Wurm-Schwanz", "Sand-Wurm-Schwanz") +N("Sand Worm W", GEN_M, "Sand-Wurm-Kopf W", " Sand-Wurm-Köpfe W", " Sand-Wurm-Kopf W", " Sand-Wurm-Kopf W") +N("Sand Worm M", GEN_M, " Sand-Wurm-Kopf M", "Sand-Wurm-Köpfe M", " Sand-Wurm-Kopf M", " Sand-Wurm-Kopf M") +N("Desert Man", GEN_M, "Wüstenbewohner", "Wüstenbewohner", "Wüstenbewohner", "Wüstenbewohner") +N("Ivy Root", GEN_F, "Efeu Wurzel", "Efeu Wurzeln", "Efeu Wurzel", "Efeu Wurzel") +N("Active Ivy", GEN_M, "Aktywny Bluszcz", "Aktywne Bluszcze", "Aktywny Bluszcz", "Aktywnym Bluszczem") +N("Ivy Branch", GEN_M, "Efeu Zweig", "Efeu Zweige", "Efeu Zweig", "Efeu Zweig") +N("Dormant Ivy", GEN_M, "Ruhende Efeu", "Ruhenden Efeu", "Ruhenden Efeu", "Ruhenden Efeu") +N("Ivy N", GEN_M, "Efeu N", " Efeu N", " Efeu N", "Efeu N") +N("Ivy D", GEN_M, " Efeu D", " Efeu D", " Efeu D", "Efeu D") +N("Giant Ape", GEN_M, "Riesige Menschenaffe", "Riesigen Menschenaffen", "Riesigen Menschenaffe", "Riesigen Menschenaffe") +N("Slime Beast", GEN_M, "Schleim Monster", "Schleim Monster", "Schleim Monster", "Schleim Monster") +N("Mirror Image", GEN_S, "Spiegelbild", "Spiegelbilder", "Spiegelbild", "Spiegelbild") +N("Mirage", GEN_F, "Trugbild", "Trugbilder", "Trugbild", "Trugbild") +N("Golem", GEN_M, "Golem", "Golems", "Golem", "Golem") +N("Eagle", GEN_M, "Adler", "Adler", "Adler", "Adler") +N("Seep", GEN_M, "Sicker", "Sicker", "Sicker", "Sicker") +N("Zombie", GEN_M, "Zombie", "Zombies", "Zombie", "Zombie") +N("Ghost", GEN_M, "Geist", "Geister", "Geist", "Geist") +N("Necromancer", GEN_M, "Totenbeschwörer", "Totenbeschwörer", "Totenbeschwörer", "Totenbeschwörer") +N("Shadow", GEN_M, "Schatten", "Schatten", "Schatten", "Schatten") +N("Tentacle", GEN_M, "Tentakel", "Tentakeln", "Tentakel", "Tentakel") +N("Tentacle Tail", GEN_M, "Tentakel", "Tentakeln", "Tentakel", "Tentakel") +N("Tentacle W", GEN_M, " Tentakel W", " Tentakeln W", " Tentakel W", " Tentakel W") +N("Tentacle M", GEN_M, " Tentakel M", " Tentakeln M", " Tentakel M", " Tentakel M") +N("Cultist", GEN_M, "Okkultist", "Okkultisten", "Okkultist", "Okkultist") +N("Fire Cultist", GEN_M, "Feuer Kultist", "Feuer Kultisten", "Feuer Kultist", "Feuer Kultist") +N("Greater Demon", GEN_M, "Grosser Demon", "Grossen Demonen", "Grossen Demon", "Grossen Demon") +N("Lesser Demon", GEN_M, "Kleine Demon", "Kleinen Demonen", "Kleinen Demon", "Kleinen Demon") +N("Ice Shark", GEN_M, "Eishai", "Eishaie", "Eishai", "Eishai") +N("Running Dog", GEN_M, "Rennende Hund", "Rennenden Hunde", "Rennenden Hund", "Rennenden Hund") +N("Demon Shark", GEN_M, "Demonenhai", "Demonenhaie", "Demonenhai", "Demonenhai") +N("Fire Fairy", GEN_F, "Feuerfee", "Feuerfeen", "Feuerfee", "Feuerfee") +N("Crystal Sage", GEN_M, "Krytsal Weiser", "Krytsal Weisen", "Krytsal Weisen", "Krytsal Weisen") +N("Hedgehog Warrior", GEN_M, "Igelkrieger", "Igelkrieger", "Igelkrieger", "Igelkrieger") +N("Tentacle (withdrawing)", GEN_M, "Tentakel (zurückziehend)", "Tentakeln (zurückziehend)", "Tentakel (zurückziehend)", "Tentakel (zurückziehend)" +// items + +N("Ice Diamond", GEN_M, "Eisdiamant", "Eisdiamanten", "Eisdiamant", "Eisdiamant") +N("Gold", GEN_S, "Gold", "-", "Gold", "Gold") +N("Spice", GEN_S, "Gewürz", "Gewürze", "Gewürz", "Gewürz") +N("Ruby", GEN_M, "Rubin", "Rubine", "Rubin", "Rubin") +N("Elixir of Life", GEN_S, "Elixier des lebens", "Elixiere des lebens", "Elixier des lebens", "Elixier des lebens") +N("Shard", GEN_F, "Scherbe", "Scherben", "Scherbe", "Scherbe") +N("Necromancer's Totem", GEN_M, "Toten-Stab", "Toten-Stäbe", "Toten-Stab", "Toten-Stab") +N("Demon Daisy", GEN_S, "Demonenblümchen", "Demonenblümchen", "Demonenblümchen", "Demonenblümchen") +N("Statue of Cthulhu", GEN_F, "Statue von Cthulhu", "Statuen von Cthulhu", "Statue von Cthulhu", "Statue von Cthulhu") +N("Phoenix Feather", GEN_N, "Feder des Phönix", "Feder des Phönix", "Feder des Phönix", "Feder des Phönix") +N("Ice Sapphire", GEN_M, "Eissaphir", "Eissaphire", "Eissaphir", "Eissaphir") +N("Hyperstone", GEN_M, "Hyperstein", "Hypersteine", "Hyperstein", "Hyperstein") +N("Key", GEN_M, "Schlüssel", "Schlüssel", "Schlüssel", "Schlüssel") +N("Dead Orb", GEN_F, "Tote Perle", "Tote Perlen", "Tote Perle", "Tote Perle") +N("Fern Flower", GEN_F, "Farnblüte", "Farnblüten", "Farnblüte", "Farnblüte") +N("Orb of Yendor", GEN_F, "Perle von Yendor", "Perlen von Yendor", "Perle von Yendor", "Perle von Yendor") +// orbs: we are using a macro here +#define Orb(E, P) N("Orb of "E, GEN_F, "Perle "D, "Perlen "D, "Perle"D, "Perle"D) +Orb("Storms", "des Donners") +Orb("Flash", "des Blitzes") +Orb("Winter", "des Winters") +Orb("Speed", "der Geschwindigkeit") +Orb("Life", "des Lebens") +Orb("Shielding", "des Schutzes") +Orb("Teleport", "des Teleportierens") +Orb("Safety", "der Sicherheit") +Orb("Thorns", "der Dornen") +// terrain features +N("none", GEN_O, "keines", "keines", "keines", "keines") +N("ice wall", GEN_F, "Eiswand", "Eiswände", "Eiswand", "Eiswand") +N("great wall", GEN_F, "Grosse Mauer", "Grosse Mauern", "Grosse Mauer", "Grosse Mauer") +N("red slime", GEN_F, "roter Schleim", "rote Schleime", "roten Schleim", "roten Schleim") +N("blue slime", GEN_F, "blaue Schleim", "blauen Schleime", "blauen Schleim", "blauen Schleim") +N("living wall", GEN_F, "Lebende Wand", "Lebenden Wände", "Lebende Wand", "Lebenden Wand") +N("living floor", GEN_M, "Lebende Boden", "Lebenden Böden", "Lebenden Boden", "Lebenden Boden") +N("dead troll", GEN_M, "tote Troll" ,"toten Trolle", "toten Troll", "toten Troll") +N("sand dune", GEN_F, "Sanddüne", "Sanddünen", "Sanddüne", "Sanddüne") +N("Magic Mirror", GEN_M, "Magische Spiegel", "Magischen Spiegel", "Magischen Spiegel", "Magischen Spiegel") +N("Cloud of Mirage", GEN_F, "Wolke des Trugbildes", "Wolken der Trugbilder", "Wolke des Trugbildes", "Wolke des Trugbildes") +N("Thumper", GEN_M, "Pseudoschild", "Pseudoschilde", "Pseudoschild", "Pseudoschild") +N("Bonfire", GEN_N, "Feuer", "Feuer", "Feuer", "Feuer") +N("ancient grave", GEN_S, "alte Grab", "alten Gräb", "alten Grab", "alten Grab") +N("fresh grave", GEN_S, "frische Grab", "frischen Gräber", "frischen Grab", "frischen Grab") +N("column", GEN_F, "Säule", "Säule", "Säule", "Säule") +N("lake of sulphur", GEN_M, "Schwefelsee", "Schwefelseen", "Schwefelsee", "Schwefelsee") +N("lake", GEN_M, "See", "Seen", "See", "See") +N("frozen lake", GEN_M, "gefrorene See", "gefrorenen Seen", "gefrorenen See", "gefrorenen See") +N("chasm", GEN_M, "Abgrund", "Abgründe", "Abgrund", "Abgrund") +N("big tree", GEN_N, "grosser Baum", "grossen Bäume", "grossen Baum", "grossen Baum") +N("tree", GEN_N, "Baum", "Bäume", "Baum", "Baum") +// lands +N("great wall", GEN_F, "Grosse Mauer", "Grosse Mauern", "Grosse Mauer", "Grosse Mauer") +N("Crossroads", GEN_F, "Kreuzung", "Kreuzungen", "Kreuzung", "Kreuzung") +N("Desert", GEN_F, "Wüste", "Wüste", "Wüste", "Wüste") +N("Icy Land", GEN_N, "eisige Land", "eisigen Länder", "eisigen Land", "eisigen Land") +N("living wall", GEN_F, "Lebende Wand", "Lebenden Wände", "Lebende Wand", "Lebenden Wand") +N("Jungle", GEN_M, "Jungel", "Jungeln", "Jungel", "Jungel") +N("Alchemist Lab", GEN_N, "Labor", "Labore", "Labor", "Labor") +N("Mirror Land", GEN_N, "Spiegelland", "Spiegelländer", "Spiegelland", "Spiegelland") +N("Graveyard", GEN_M, "Friedhof", "Friedhöffe", "Friedhof", "Friedhof") +N("R'Lyeh", GEN_N, "R'Lyeh", "R'Lyeh", "R'Lyeh", " R'Lyeh") +N("Hell", GEN_F, "Hölle", "Höllen", "Hölle", "Hölle") +N("Cocytus", GEN_M, "Kocyt", "Kocyt", "Kocytu", "w Kocycie") +N("Land of Eternal Motion", GEN_N, "Land der ewigen Bewegung", "Länder der ewigen Bewegung", "Land der ewigen Bewegung", "Land der ewigen Bewegung") +N("Dry Forest", GEN_M, "trockene Wald", "trockenen Wälder", "trockenen Wald", "trockenen Wald") +N("Game Board", GEN_N, "Spielbrett", "Spielbretter", "Spielbrett", "Spielbrett") + +// Game messages + +// fighting messages + +// For each English form, provide a Polish form. Player is referred to via %...0, +// and objects are referred to via %...1 and %...2. For example, in Polish: + +// %a1 refers to the accusative form of the first object (as explained above in 'Nouns') +// likewise, %a2 refers to the accusative form of the second object +// %Å‚1 is replaced by "Å‚", "Å‚o" or "Å‚a", depending on the gender of %1 +// %Å‚eÅ›0 adds "Å‚eÅ›" or "Å‚aÅ›" depending on the gender of the player + +// Use whatever %xxx# codes you need for your language. Of course, +// tell me how your codes should be expanded. + +S("You kill the %1.", "Du tötest %den1 %a1.") +S("You would be killed by the %1!", "Du würdest von %den1 %a1 getötet werden!") +S("The %1 would get you!", "%Der1 %n1 würde dich fangen!") +S("The %1 destroys the %2!", "%Der1 %n1 zerstört %den2 %a2!") +S("The %1 eats the %2!", "%Der1 %n1 frisst %den2 %a2!") +S("The ivy destroys the %1!", "Das Efeu zerstört %den1 %a1!") +S("The %1 claws the %2!", "%Der1 %n1 kratzt %den2 %a2!") +S("The %1 scares the %2!", "%Der1 %n1 erschreckt %den2 %a2!") +S("The %1 melts away!", "%Der1 %n1 schmilzt!") +S("The %1 stabs the %2.", "%Der1 %n1 ersticht %den2 %a2.") +S("You stab the %1.", "Du erstichst %den1 %a1.") + +S("You cannot attack the %1 directly!", "Du kannst %den1 %a1 nicht direkt angreifen!") +S("Stab them by walking around them.", "Ersteche sie indem du um sie herumläufst.") + +S("You feel more experienced in demon fighting!", "Du fühlst dich besser erfahren in Dämonenbekämpfung!") +S("Cthulhu withdraws his tentacle!", "Cthulhu zieht sein Tentakel zurück!") +S("The sandworm explodes in a cloud of Spice!", "Der Sandwurm explodiert in eine Wolke von Gewürzen!") +S("The %1 is confused!", "%Der1 %n1 ist verwirrt.") +S("The %1 raises some undead!", "%Der1 %n1 erweckt die Toten!") +S("The %1 throws fire at you!", "%Der1 n1 wirft Feuer nach dir!") +S("The %1 shows you two fingers.", "%Der1 %n1 zeigt dir zwei Finger.") +S("You wonder what does it mean?", "Du wunderst dich was es bedeutet.") +S("The %1 shows you a finger.", "%Der1 %n1 zeigt dir ein Finger.") +S("You think about possible meanings.", "Du denkst über mögliche Bedeutungen.") +S("The %1 moves his finger downwards.", "%Der1 %n1 bewegt sein Finger nach unten.") +S("Your brain is steaming.", "Dein Hirn dampft.") +S("The %1 destroys the %2!", "%Der1 %n1 zerstört %den2 %a2!") +S("You join the %1.", "PoÅ‚Ä…czy%Å‚eÅ›0 siÄ™ z %abl1.") +S("Two of your images crash and disappear!", "Zwei %np1 stürzen gegeneinander!") +S("The %1 breaks the mirror!", "%Der1 %n1 zerstört den Spiegel!") +S("The %1 disperses the cloud!", "%Der1 %n1 verstreut die Wolke!") +S("You activate the Flash spell!", "Du aktivierst den Blitzzauber!") +S("You activate the Lightning spell!", "Du aktivierst den Donnerzauber!") +S("Ice below you is melting! RUN!", "Das Eis unter dir schmilzt! RENNE!") +S("This spot will be burning soon! RUN!", "Dieser Ort wird bald brennen! RENNE!") +S("The floor has collapsed! RUN!", "Der Boden ist zusammengebrochen! RENNE!") +S("You need to find the right Key to unlock this Orb of Yendor!", + "Du musst den richtigen Schlüssel finden um die Perle von Yendor zu öffnen!") +S("You fall into a wormhole!", "Du fällst in ein Wurmloch!") +S("You activate the %1.", "Du aktivierst %den1 %a1.") +S("No room to push the %1.", "Kein Raum um %den1 %a1 zu schieben.") +S("You push the %1.", "Du schiebst %den1 %a1.") +S("You start cutting down the tree.", "Du fängst an den Baum zu schneiden.") +S("You cut down the tree.", "Du schneidest den Baum.") +S("You cannot attack Sandworms directly!", "Du kannst Sandwürmer nicht direkt angreifen!") +S("You cannot attack Tentacles directly!", "Du kannst Tentakeln nicht direkt angreifen!") +S("You cannot defeat the Shadow!", "Du kannst den Schatten nicht besiegen!") +S("You cannot defeat the Greater Demon yet!", "Du kannst den Grossen Demon noch nicht besiegen!") +S("That was easy, but groups could be dangerous.", "Das war einfach, aber Gruppen könnten gefährlich sein.") +S("Good to know that your fighting skills serve you well in this strange world.", "Gut zu wissen das deine Kampfkünste dir in dieser ungewöhnlichen Welt gut helfen.") +S("You wonder where all these monsters go, after their death...", "Du wunderst dich wo all diese Monster nach ihrem Tot hingehen...") +S("You feel that the souls of slain enemies pull you to the Graveyard...", "Du hast das Gefühl, dass die Seelen gefallener Gegner dich zum Friedhof führen...") +S("Wrong color!", "Falsche Farbe!") +S("You cannot move through the %1!", "Du kannst nicht durch %den1 %a1 gehen!") +S("The %1 would kill you there!", "%Der1 %n1 würde dich dort töten!") +S("Wow! %1! This trip should be worth it!", "Wow, %n1! Dieser trip sollte es Wert sein!") +S("For now, collect as much treasure as possible...", "Für jetzt, sammle so viele Schätze wie möglich ein...") +S("Prove yourself here, then find new lands, with new quests...", "Beweise dich hier, finde dann neue Länder, mit neuen Herausforderungen...") +S("You collect your first %1!", "Du sammelst dein erstes %a1 ein!") +S("You have found the Key! Now unlock this Orb of Yendor!", "Du hast den Schlüssel gefunden! Jetzt musst du die Perle von Yendor finden und öffnen!") +S("This orb is dead...", "Diese Perle ist tot...") +S("Another Dead Orb.", "Eine weitere tote Perle.") +S("You have found the %1!", "Du hast %den1 %a1 gefunden!") +S("You feel that the %2 becomes more dangerous.", "Du spürst, dass %der2 %n2 gefährlicher wird.") +S("With each %1 you collect...", "Mit...") +S("Are there any magical orbs in the %1?...", "Gibt es irgenwelche magischen Perlen in %dem1 %d1?") +S("You feel that the %1 slowly becomes dangerous...", "Du spürst wie %der1 %n1 langsam gefährlich wird...") +S("Better find some other place.", "Such dir lieber einen anderen Ort.") +S("You have a vision of the future, fighting demons in Hell...", "Masz wizjÄ™ przyszÅ‚oÅ›ci, w której walczysz z demonami w Piekle...") +S("With this Elixir, your life should be long and prosperous...", "Mit diesem Elixir sollte dein Leben lang und wohlhabend sein...") +S("The Necromancer's Totem contains hellish incantations...", "Der Toten-stab enthält höllische Zauberformeln...") +S("The inscriptions on the Statue of Cthulhu point you toward your destiny...", "Die Gravuren auf der Statue von Cthulhu erzählen von deinen Schicksal...") +S("Still, even greater treasures lie ahead...", "Trotzdem, es erwarten dich immer noch grössere Schätze...") +S("You collect the %1.", "Du sammelst %den1 %a1.") +S("CONGRATULATIONS!", "GLÜCKWUNSCH!") +S("Collect treasure to access more different lands...", "Sammle Schätze ein um neue Länder zu erreichen...") +S("You feel that you have enough treasure to access new lands!", "Du hast das Gefühl, dass du genug Schätze hast um neue Länder zu erreichen!") +S("Collect more treasures, there are still more lands waiting...", "Sammle mehr Schätze ein, es gibt immer noch Länder welche auf dich warten...") +S("You feel that the stars are right, and you can access R'Lyeh!", "Du hast das Gefühl, dass die Sterne richtig angeordnet sind und R'Lyeh erreichen kannst!") +S("Kill monsters and collect treasures, and you may get access to Hell...", "Töte Monster und sammle Schätzte ein, und vielleicht kriegst du Zugang zur Hölle...") +S("To access Hell, collect 10 treasures each of 9 kinds...", "Um die Hölle zu erreichen, sammle 10 Schätze in 9 verschiedene Ländern...") +S("Abandon all hope, the gates of Hell are opened!", "Gib alle Hoffnung auf, die Tore zur Hölle sind offen!") +S("And the Orbs of Yendor await!", "Und die Perlen von Yendor erwarten dich!") +S("You switch places with the %1.", "Du tauscht Plätze mit .") + +S("You rejoin %the1.", "Połączy%łeś1 się z %abl1.") +S("The mirror shatters!", "Lustro pęka!") +S("The cloud turns into a bunch of images!", "Chmura zamienia się w obrazy!") +S("The slime reacts with %the1!", "Maź reaguje z %abl1!") +S("You drop %the1.", "Porzuci%łeś0 %a1.") +S("You feel great, like a true treasure hunter.", "Czujesz się świenie, jak prawdziwy łowca skarbów.") +S("Your eyes shine like gems.", "Twoje oczy błyszczą jak klejnoty.") +S("Your eyes shine as you glance at your precious treasures.", "Twoje oczy błyszczą, gdy patrzysz na swoje skarby.") +S("You glance at your great treasures.", "Patrzysz na swoje wspaniałe skarby.") +S("You glance at your precious treasures.", "Patrzysz na swoje drogocenne skarby.") +S("You glance at your precious treasure.", "Patrzysz na swój drogocenny skarb.") +S("Your inventory is empty.", "Nie masz żadnych skarbów.") +S("You teleport to a new location!", "Teleportujesz się do nowego miejsca!") +S("Could not open the score file: ", "Nie udało się otworzyć pliku: ") +S("Game statistics saved to %1", "Statystyki gry zapisane do %1") +S("Game loaded.", "Gra odczytana.") +S("You summon some Mimics!", "Przywoła%łeś0 Miraże!") +S("You summon a golem!", "Przywoła%łeś0 Golema!") +S("You will now start your games in %1", "Będziesz zaczynał grę %abl1") +S("Activated the Hyperstone Quest!", "Aktywowałeś Misję Hiperkamień!") +S("Orb power depleted!", "Zabrano sfery mocy!") +S("Orbs summoned!", "Sfery mocy przywołane!") +S("Orb power gained!", "Zdobyta moc!") +S("Dead orbs gained!", "Zdobyte Martwe Sfery!") +S("Orb of Yendor gained!", "Zdobyta Sfera Yendoru!") +S("Treasure gained!", "Skarb zdobyty!") +S("Lots of treasure gained!", "Mnóstwo skarbów zdobyte!") +S("You summon a sandworm!", "Przywoła%łeś0 Czerwia!") +S("You summon an Ivy!", "Przywoła%łeś0 Bluszcz!") +S("You summon a monster!", "Przywoła%łeś0 potwora!") +S("You summon some Thumpers!", "Przywoła%łeś0 dudniki!") +S("You summon a bonfire!", "Przywoła%łeś0 ognisko!") +S("Treasure lost!", "Skarb utracony!") +S("Kills gained!", "Zdobyto trupy!") +S("Activated Orb of Safety!", "Aktywowano Sferę Bezpieczeństwa!") +S("Teleported to %1!", "Przeniesiono w %abl1") + +S("Welcome to HyperRogue", "Witaj w HyperRogue") +S(" for Android", " na Android") +S(" for iOS", " na iOS") +S("! (version %1)\n\n", "! (wersja %1)\n\n") +S(" (press ESC for some hints about it).", " (naciśnij ESC by dostać wskazówki).") +S("Press 'c' for credits.", "Naciśnij 'c' by obejrzeć autorów") +S("game design, programming, texts and graphics by Zeno Rogue \n\n", + "projekt, programowanie, teksty i grafika: Zeno Rogue \n\n") +S("add credits for your translation here", "Teksty i tłumaczenie: Zeno Rogue\n\n") +S(" (touch to activate)", " (dotknij, by aktywować)") +S(" (expired)", " (wyczerpany)") +S(" [%1 turns]", " [kolejek: %1]") +S(", you", ", Ty") +S("0 = Klein model, 1 = Poincaré model", "0 = model Kleina, 1 = model Poincaré") +S("you are looking through it!", "patrzysz przez hiperboloidę!") +S("simply resize the window to change resolution", "po prostu zmień rozmiar okna") +S("[+] keep the window size, [-] use the screen resolution", "[+] zachowaj rozmiar okna, [-] użyj rozdzielczości ekranu") +S("+5 = center instantly, -5 = do not center the map", "+5 = centruj natychmiast, -5 = nie centruj") +S("press Space or Home to center on the PC", "naciśnij Space lub Home, by wycentrować na postaci") +S("You need special glasses to view the game in 3D", "Potrzebujesz specjalnych okularów, by oglądać grę w 3D") +S("You can choose one of the several modes", "Możesz wybrać jeden z kilku trybów") +S("ASCII", "ASCII") +S("black", "czarny") +S("plain", "prosty") +S("Escher", "Escher") +S("items only", "tylko przedmioty") +S("items and monsters", "przedmioty i potwory") +S("no axes", "bez osi") +S("auto", "auto") +S("light", "lekki") +S("heavy", "gruby") +S("The axes help with keyboard movement", "Osie pomagają, gdy gramy na klawiaturze") +S("Config file: %1", "Plik konfiguracyjny: %1") +S("joystick mode: automatic (release the joystick to move)", "tryb dżojstika: automatyczny (puść by ruszyć)") +S("joystick mode: manual (press a button to move)", "tryb dżojstika: ręczny (naciśnij przycisk)") +S("Reduce the framerate limit to conserve CPU energy", "Ogranicz fps, by oszczędzać energię") +S("Press F1 or right click for help", "Wciśnij F1 lub kliknij prawym, by uzyskać pomoc") +S("No info about this...", "Brak informacji o tym...") +S("Press Enter or F10 to save", "Wciśnij Enter lub F10, by zapisać i wyjść") +S("Press Enter or F10 to quit", "Wciśnij Enter lub F10, by wyjść z gry") +S("or 'r' or F5 to restart", "lub 'r' lub F5, by zacząć od początku") +S("or 't' to see the top scores", "lub 't' by zobaczyć najlepsze wyniki") +S("or another key to continue", "lub inny klawisz, by kontynuować") +S("It is a shame to cheat!", "Wstyd oszukiwać!") +S("Showoff mode", "Tryb pokazowy") +S("Quest status", "Stan misji") +S("GAME OVER", "KONIEC GRY") +S("Your score: %1", "Twój wynik: %1") +S("Enemies killed: %1", "Potwory pokonane: %1") +S("Orbs of Yendor found: %1", "Znalezione Sfery Yendoru: %1") +S("Collect 30 $$$ to access more worlds", "Znajdź 30 $$$ by iść do nowych krain") +S("Collect at least 10 treasures in each of 9 types to access Hell", "Znajdź po 10 skarbów w 9 typach, by się dostać do Piekła") +S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Znajdź 10 Czarciego Ziela, by znaleźć Sfery Yendoru") +S("Hyperstone Quest: collect at least 10 %1 in %the2", "Misja alternatywna: znajdź co najmniej 10 skarbów %abl2") +S("Hyperstone Quest completed!", "Misja alternatywna zakończona!") +S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Szukaj Sfer Yendoru w Piekle albo na Skrzyżowaniu!") +S("Unlock the Orb of Yendor!", "Otwórz Sferę Yendoru!") +S("Defeat 100 enemies to access the Graveyard", "Pokonaj 100 przeciwników, by trafić na Cmentarz") +S("(press ESC during the game to review your quest)", "(naciśnij ESC w trakcie gry, by zobaczyć stan swojej misji)") +S("you have cheated %1 times", "liczba oszustw: %1") +S("%1 turns (%2)", "kolejek: %1 (%2)") +S("last messages:", "ostatnie wiadomości: ") +S("time elapsed", "czas") +S("date", "data") +S("treasure collected", "zdobyte skarby") +S("total kills", "łączne zabicia") +S("turn count", "liczba kolejek") +S("cells generated", "wygenerowane pola") +S("t/left/right - change display, up/down - scroll, s - sort by", "lewo/prawo - zmiana, góra/dół - przewijanie, s - sortowanie") +S("kills", "zab") +S("time", "czas") +S("ver", "wer") +S("SORT", "SORT") +S("PLAY", "GRA") +S("Your total wealth", "Twoje łączne bogactwo") +S("treasure collected: %1", "zdobyte skarby: %1") +S("objects found: %1", "znalezione przedmioty: %1") +S("orb power: %1", "moc: %1") +S(" (click to drop)", " (naciśnij by porzucić)") +S("You can also scroll to the desired location and then press 't'.", "Możesz też przewinąć do miejsca docelowego i wcisnąć 't'.") +S("Thus, it is potentially useful for extremely long games, which would eat all the memory on your system otherwise.\n", + "Jest więc to użyteczne w bardzo długich grach, które inaczej by zjadły całą pamięć.") +S("You can touch the Dead Orb in your inventory to drop it.", "Dotknij Martwej Sfery na liście, by ją porzucić.") +S("This might be useful for Android devices with limited memory.", "To może się przydać, gdy Twoje urządzenie ma mało pamięci.") +S("You can press 'g' or click them in the list to drop a Dead Orb.", "Wciśnij 'g' lub kliknij Martwe Sfery na liście, by je porzucić.") +S("frames per second", "klatki na sekundę") +S("monsters killed: %1", "pokonane potwory: %1") +S("Drawing %1 (layer %2), F1 for help", "Rysujemy %1 (warstwa %2), F1 - pomoc") +S("hepta floor", "podłoga hepta") +S("hexa floor", "podłoga hex") +S("character", "postać") +S("ESC for menu/quest", "ESC - menu/misja") +S("vector graphics editor", "edytor grafiki wektorowej") +S("cheat mode", "tryb oszusta") +S("heptagonal game board", "plansza do gry z siedmiokątów") +S("triangular game board", "plansza do gry z trójkątów") +S("HyperRogue game board", "plansza do gry HyperRogue") +S("first page [Space]", "pierwsza strona [Space]") +S("exit configuration", "wyjdź z konfiguracji") +S("Configuration:", "Konfiguracja:") +S("video resolution", "rozdzielczość obrazu") +S("fullscreen mode", "tryb pełnoekranowy") +S("animation speed", "prędkość animacji") +S("dist from hyperboloid ctr", "odległość od centrum hiperboloidy") +S("scale factor", "współczynnik skali") +S("wall display mode", "tryb pokazywania ścian") +S("monster display mode", "tryb pokazywania potworów") +S("cross display mode", "tryb pokazywania osi") +S("background music volume", "głośność muzyki tła") +S("OFF", "WYŁ") +S("ON", "WŁ") +S("distance between eyes", "odległość między oczami") +S("framerate limit", "ograniczenie na fps") +S("joystick mode", "tryb dżojstika") +S("automatic", "automatyczny") +S("manual", "ręczny") +S("language", "język") +S("EN", "PL") +S("player character", "postać gracza") +S("male", "mężczyzna") +S("female", "kobieta") +S("use Shift to decrease and Ctrl to fine tune ", "użyj Shift by zmniejszyć, Ctrl by zwiększyć dokładność") +S("(e.g. Shift+Ctrl+Z)", " (na przykład Shift+Ctrl+Z)") +S("the second page [Space]", "druga strona [Space]") +S("special features [Space]", "opcje specjalne [Space]") +S("exit configuration", "wyjdź z konfiguracji") +S("see the help screen", "obejrzyj ekran pomocy") +S("save the current config", "zapisz obecną konfigurację") +S("(v) config", "(v) ust.") +S("Screenshot saved to %1", "Zrzut ekranu zapisany do %1") +S("You need an Orb of Teleport to teleport.", "Potrzebujesz Sfery Teleportacji, by to zrobić.") +S("Use arrow keys to choose the teleport location.", "Użyj strzałek, by wybrać cel teleportacji.") +S("openGL mode enabled", "włączono tryb OpenGL") +S("openGL mode disabled", "wyłączono tryb OpenGL") +S("openGL & antialiasing mode", "openGL i antialiasing") +S("anti-aliasing enabled", "włączono anti-aliasing") +S("anti-aliasing disabled", "wyłączono anti-aliasing") +S("You activate your demonic powers!", "Aktywowałeś moce demoniczne!") + +// Steam achievement messages + +S("New Achievement:", "Nowe osiągnięcie:") +S("Your total treasure has been recorded in the Steam Leaderboards.", "Twój wynik został zapisany w rankingach Steam.") +S("Congratulations!", "Gratulacje!") +S("You have improved your total high score and %1 specific high scores!", "Poprawi%łeś0 swój ogólny najlepszy wynik oraz %1 z wyników szczegółowych!") +S("You have improved your total and '%1' high score!", "Poprawi%łeś0 swój wynik ogólny, oraz swój wynik w kategorii '%P1!'") +S("You have improved your total high score on Steam. Congratulations!", "Poprawi%łeś0 swój ogólny najlepszy wynik na Steam. Gratulacje!") +S("You have improved %1 of your specific high scores!", "Poprawi%łeś0 %1 z wyników szczegółowych!") +S("You have improved your '%1' high score on Steam!", "Poprawi%łeś0 swój wynik w kategorii '%P1' na Steam!") +S("You have collected 10 treasures of each type.", "Znalaz%łeś0 10 skarbów każdego typu.") +S("This is your first victory!", "To Twoje pierwsze zwycięstwo!") +S("This has been recorded in the Steam Leaderboards.", "To zostało zapisane w Rankingach Steam.") +S("The faster you get here, the better you are!", "Im szybciej to osiągniesz, tym lepiej!") +S("You have improved both your real time and turn count. Congratulations!", "Poprawi%łeś0 swój najlepszy czas rzeczywisty i liczbę ruchów. Gratulacje!") +S("You have used less real time than ever before. Congratulations!", "Zajęło to mniej czasu rzeczywistego, niż wcześniej. Gratulacje!") +S("You have used less turns than ever before. Congratulations!", "Zajęło to mniej kolejek, niż kiedykolwiek wcześniej. Gratulacje!") + +// help texts. These are separated into multiple lines just for convenience, +// you don't have to follow. + +S( + "You have been trapped in a strange, non-Euclidean world. Collect as much treasure as possible " + "before being caught by monsters. The more treasure you collect, the more " + "monsters come to hunt you, as long as you are in the same land type. The " + "Orbs of Yendor are the ultimate treasure; get at least one of them to win the game!", + + "Trafi%łeś0 do dziwnej, nieeuklidesowej krainy. Zdobądź jak najwięcej skarbów, " + "zanim potwory Ciebie dopadną. Im więcej zdobędziesz skarbów, tym więcej potworów " + "w danej krainie na Ciebie poluje. Sfery Yendora są skarbem ostatecznym: zdobądź " + "Sferę Yendora, by wygrać grę!" + ) + +S( + "You can fight most monsters by moving into their location. " + "The monster could also kill you by moving into your location, but the game " + "automatically cancels all moves which result in that.\n\n", + + "Większość przeciwników zabijasz poprzez wejście na zajmowane przez nie pole. " + "Przeciwnik może Ciebie zabić w ten sam sposób, ale gra automatycznie zabrania " + "ruchów, które by do tego prowadziły.\n\n") + +S( + "Usually, you move by touching somewhere on the map; you can also touch one " + "of the four buttons on the map corners to change this (to scroll the map " + "or get information about map objects). You can also touch the " + "numbers displayed to get their meanings.\n", + "Zazwyczaj poruszasz się przez dotknięcie pola na mapie; możesz również " + "dotknąć jednego z przycisków w rogach, by to zmienić (by przewijać mapę albo " + "zdobyć informacje). Możesz też dotknąć liczb na ekranie, by poznać ich " + "znaczenie.\n") + +S("Move with mouse, num pad, qweadzxc, or hjklyubn. Wait by pressing 's' or '.'. Spin the world with arrows, PageUp/Down, and Home/Space. " + "To save the game you need an Orb of Safety. Press 'v' for config, ESC for the quest status and menu.\n\n", + "Ruszasz się myszą, klawiaturą numeryczną, qweadzxc, lub hjklyubn. Czekasz naciskając 's' lub '.'. " + "Obracasz świat strzałkami, PgUp/Dn, lub Home/Space. Naciśnij 'v' by zmienić ustawienia, ESC " + "by zobaczyć stan misji i menu.\n\n") + +S("See more on the website: ", "Więcej na stronie: ") + +S("special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n", + "Szczególne podziękowania dla poniższych osób za zgłoszone przez nich błędy, pomysły, porty i inną pomoc:\n\n%1\n\n") + +S( + "The total value of the treasure you have collected.\n\n" + "Every world type contains a specific type of treasure, worth 1 $$$; " + "your goal is to collect as much treasure as possible, but every treasure you find " + "causes more enemies to hunt you in its native land.\n\n" + "Orbs of Yendor are worth 50 $$$ each.\n\n", + + "Łączna wartość Twoich skarbów.\n\n" + "Każda kraina zawiera specyficzny dla niej skarb, wart 1 $$$; " + "Twoim celem jest zebranie jak najwięcej skarbów, ale każdy " + "znaleziony skarb powoduje, że w jego krainie więcej potworów na Ciebie poluje.\n\n" + "Sfery Yendoru są warte po 50 $$$.\n\n") + +S( + "The higher the number, the smoother the animations in the game. " + "If you find that animations are not smooth enough, you can try " + "to change the options ", + "Im większa liczba, tym płynniejsze są animacje. Jeśli animacja nie " + "jest dostatecznie płynna, spróbuj zmienić opcje") + +S("(Menu button) and select the ASCII mode, which runs much faster. " + "Depending on your device, turning the OpenGL mode on or off might " + "make it faster, slower, or cause glitches.", + "(Menu), tryb ASCII działa dużo szybciej. Tryb OpenGL również wpływa " + "na jakość grafiki." + ) + +S("(in the MENU). You can reduce the sight range, this should make " + "the animations smoother.", + "(w MENU). Możesz zmniejszyć zasięg widzenia, dzięki temu animacje " + "będą płynniejsze.") + +S("(press v) and change the wall/monster mode to ASCII, or change " + "the resolution.", + "(naciśnij 'v') i zmień tryb ścian/potworów na ASCII, albo zmień " + "rozdzielczość.") + +S( + "In this mode you can draw your own player character and floors. " + "Mostly for the development purposes, but you can have fun too.\n\n" + "f - floor, p - player (repeat 'p' for layers)\n\n" + "n - new shape, u - copy the 'player body' shape\n\n" + "1-9 - rotational symmetries, 0 - toggle axial symmetry\n\n" + "point with mouse and: a - add point, m - move nearest point, d - delete nearest point, c - nearest point again, b - add after nearest\n\n" + "s - save in C++ format (but cannot be loaded yet without editing source)\n\n" + "z - zoom, o - Poincaré model\n", + + "W tym trybie możesz narysować swoją własną postać albo podłogę. " + "Głównie w celu rozwijania gry, ale Ty też możesz się pobawić.\n\n" + "f - podłoga, p - gracz (powtarzaj, by zmienić warstwę)\n\n" + "n - nowy kształt, u - skopiuj standardową postać gracza\n\n" + "1-9 - symetrie obrotowe, 0 - symetria osiowa\n\n" + "wskaż myszą i: a - dodaj punkt, m - przesuń najbliższy punkt, d - skasuj najbliższy punkt, c - powtórz najbliższy punkt, b - po najbliższym\n\n" + "s - zapisz w formacie C++ (niestety obecnie nie można wczytać bez edytowania źródeł gry)\n\n" + "z - powiększenie, o - model Poincaré\n") + +S( + "These huge monsters normally live below the sand, but your movements have " + "disturbed them. They are too big to be slain with your " + "weapons, but you can defeat them by making them unable to move. " + "This also produces some Spice. They move two times slower than you.", + + "Te wielkie stworzenia normalnie żyją pod pustynnym piaskiem, ale Twoja obecność " + "na pustyni spowodowała ich wyjście na powierzchnię. Są za duże, byś m%ógł0 je " + "zaatakować swoją bronią, ale zginą, jeśli nie będą mogły się ruszyć -- to " + "produkuje także trochę Przyprawy. Czerwie ruszają się 2 razy wolniej od Ciebie.") + +S("The tentacles of Cthulhu are like sandworms, but longer. " + "They also withdraw one cell at a time, instead of exploding instantly.", + + "Macki Cthulhu są podobne do Pustynnych Czerwi, ale dłuższe. " + "W przeciwieństwie do nich, nie eksplodują po zablokowaniu, tylko cofają się " + "pod ziemię, po 1 polu na kolejkę.") + +S( + "A huge plant growing in the Jungle. Each Ivy has many branches, " + "and one branch grows per each of your moves. Branches grow in a clockwise " + "order. The root itself is vulnerable.", + "Wielka roślina z dżungli. Bluszcz zazwyczaj ma wiele gałęzi, po każdym Twoim " + "ruchu jedna z nich rośnie. Gałęzie rosną w kolejnosci zegarowej. Sam korzeń " + "nie atakuje, zatem goły korzeń łatwo ściąć.\n") + +S("The Alchemists produce magical potions from pools of blue and red slime. You " + "can go through these pools, but you cannot move from a blue pool to a red " + "pool, or vice versa. Pools containing items count as colorless, and " + "they change color to the PC's previous color when the item is picked up. " + "Slime beasts also have to keep to their own color, " + "but when they are killed, they explode, destroying items and changing " + "the color of the slime and slime beasts around them.", + "Alchemicy produkują magiczne napoje z niebieskiej i czerwonej mazi. Możesz " + "poruszać się poprzez maź, ale nie możesz przesunąć się z pola niebieskiego " + "na czerwone, ani z powrotem. Pola zawierające przedmioty są bezbarwne, " + "jak zabierzemy przedmiot, to zmieniają kolor na kolor pola, na którym " + "gracz był wcześniej. Maziste Stwory również ograniczone są do swojego koloru. " + "Gdy je zabijesz, eksplodują, niszcząc przedmioty i zmieniając kolor mazi wokół nich.\n") + +S( + "These creatures are slow, but very powerful... more powerful than you. " + "You need some more experience in demon fighting before you will be able to defeat them. " + "Even then, you will be able to slay this one, but more powerful demons will come...\n\n" + "Each 10 lesser demons you kill, you become powerful enough to kill all the greater " + "demons on the screen, effectively turning them into lesser demons.", + + "Te demony są powolne, ale bardzo silne... silniejsze od Ciebie. " + "Potrzebujesz zdobyć trochę doświadczenia, zanim będziesz w stanie je pokonać. " + "Nawet wtedy, przyjdą jeszcze silniejsze demony...\n\n" + "Za każdym razem, gdy pokonasz 10 mniejszych demonów, stajesz się dostatecznie silny, " + "by pokonać wszystkie Wielkie Demony na ekranie. Stają się one w tym momencie " + "Mniejszymi Demonami.") + +S("These creatures are slow, but they often appear in large numbers.", + "Te demony są powolne, ale często pojawiają się w dużych ilościach.") + +S("A big monster from the Living Caves. A dead Troll will be reunited " + "with the rocks, causing some walls to grow around its body.", + "Duży stwór z Żyjących Jaskiń. Martwy Troll połączy się ze skałą, " + "powodując rozrost skał wokół jego ciała.") + +S("Huge, impassable walls which separate various lands.", + "Wielkie ściany, które oddzielają od siebie poszczególne krainy.") + +S( + "This cave contains walls which are somehow living. After each turn, each cell " + "counts the number of living wall and living floor cells around it, and if it is " + "currently of a different type than the majority of cells around it, it switches. " + "Items count as three floor cells, and dead Trolls count as five wall cells. " + "Some foreign monsters also count as floor or wall cells.\n", + "Ściany tej jaskini sa żywe. W każdej kolejce, każde pole liczy, ile wokół niego " + "jest pól ściany i pól ziemi, i jeśli jest innego typu niż większość pól wokół " + "niego, to zmienia typ na przeciwny. Przedmioty liczą się jako 3 pola ziemi, " + "martwe Trolle jako 5 pól ściany. Niektóre potwory z innych krain również liczą się " + "jako ziemia lub ściana.\n") + +S( + "This forest is quite dry. Beware the bushfires!\n" + "Trees catch fire on the next turn. The temperature of the grass cells " + "rises once per turn for each fire nearby, and becomes fire itself " + "when its temperature has risen 10 times.\n" + "You can also cut down the trees. Big trees take two turns to cut down.", + "Ta puszcza jest wyschnięta. Uważaj na pożary!\n" + "Sąsiednie drzewa zajmują się ogniem w następnej kolejce. Temperatura " + "pola bez drzewa rośnie o 1 na kolejkę z każdym ogniem w sąsiedztwie, i gdy " + "wzrośnie do 10, to pole również staje się ogniem.\n" + "Możesz też ścinać drzewa. Ścięcie dużego drzewa zajmuje dwie kolejki." + ) + +S("A big and quite intelligent monster living in the Icy Land.", + "Duża i całkiem inteligentna bestia z Krainy Lodu.") + +S( + "A nasty predator from the Icy Land. Contrary to other monsters, " + "it tracks its prey by their heat.", + "Niebezpieczny drapieżnik z Krainy Lodu. W przeciwieństwie do innych " + "stworów, śledzi ofiarę po jej cieple.") + +S("Rangers take care of the magic mirrors in the Land of Mirrors. " + "They know that rogues like to break these mirrors... so " + "they will attack you!", + "Strażnicy chronią luster w Krainie Luster. Wiedzą, że złodzieje lubią " + "rozbijać lustra... także spodziewaj się ataku!") + +S("A nasty creature native to the Living Caves. They don't like you " + "for some reason.", + "Brzydki stwór z Żywych Jaskiń. Jakoś Ciebie nie lubi.") + +S("A tribe of men native to the Desert. They have even tamed the huge Sandworms, who won't attack them.", + "Plemię ludzi żyjących na Pustyni. Oswoili oni Pustynne Czerwie, dzięki czemu żyją razem pokojowo.") + +S("This giant ape thinks that you are an enemy.", "Ta małpa uważa, że jesteś jej przeciwnikiem.") + +S("A magical being which copies your movements.", "Magiczna istota kopiująca Twoje ruchy.") + +S("A magical being which copies your movements. " + "You feel that it would be much more useful in an Euclidean space.", + "Magiczna istota kopiująca Twoje ruchy. W przestrzeni euklidesowej byłaby dużo bardziej przydatna.") + +S("You can summon these friendly constructs with a magical process.", + "Przyjazna konstrukcja, tworzona poprzez magiczny proces.") + +S("A majestic bird, who is able to fly very fast.", + "Ten majestatyczny ptak bardzo szybko lata.") + +S("A monster who is able to live inside the living cave wall.", + "Sączaki żyją w ściane Żywej Jaskini.") + +S("A typical Graveyard monster.", "Typowy cmentarny stwór.") + +S("A typical monster from the Graveyard, who moves through walls.\n\n" + "There are also wandering Ghosts. They will appear " + "if you do not explore any new places for a long time (about 100 turns). " + "They can appear anywhere in the game.", + "Typowy cmentarny stwór. Może przechodzić przez ściany.\n\n" + "Są też błądzące Duchy, które pojawiają się, gdy nie zwiedzasz " + "nowych miejsc przez długi czas (około 100 kolejek). Duchy te " + "mogą pojawić się w dowolnym miejscu w grze." + ) + +S("Necromancers can raise ghosts and zombies from fresh graves.", + "Nekromanci wzbudzają duchy i zombie ze świeżych grobów.") + +S("A creepy monster who follows you everywhere in the Graveyard.", + "Ten odrażający potwór chodzi za Tobą po cmentarzu!") + +S("People worshipping Cthulhu. They are very dangerous.", + "Wyznawcy Cthulhu, bardzo niebiezpieczni.") + +S("People worshipping Cthulhu. This one is especially dangerous, " + "as he is armed with a weapon which launches fire from afar.", + "Wyznawcy cthulhu. Ten jest szczególnie niebezpieczny, bo " + "może z odległości rozpalić ogień w Twojej okolicy.") + +S("This dangerous predator has killed many people, and has been sent to Cocytus.", + "Ten niebezpieczny drapieżnik zabił wielu ludzi, i został zesłany do Kocytu.") + +S("This white dog is able to run all the time. It is the only creature " + "able to survive and breed in the Land of Eternal Motion.", + "Ten biały piesek jest w stanie biegać przez całe swoje życie. Jest to jedyne " + "stworzenie, które jest w stanie przeżyć w Krainie Wiecznego Ruchu.") + +S("Demons of Hell do not drown when they fall into the lake in Cocytus. " + "They turn into demonic sharks, enveloped in a cloud of steam.", + "Demony nie topią się, gdy wpadną w jezioro Kocyt. Zamieniają się " + "w demoniczne rekiny, otoczone chmurą pary.") + +S("These fairies would rather burn the forest, than let you get some Fern Flowers. " + "The forest is infinite, after all...\n\n" + "Fire Fairies transform into fires when they die.", + "Rusałki wolą spalić las, niż pozwolić Ci zdobyć Kwiaty Paproci. W końcu " + "las jest nieskończony...\n\n" + "Rusałki zamieniają się w ogień, gdy giną.") + +S("These warriors of the Forest wield exotic weapons called hedgehog blades. " + "These blades protect them from a frontal attack, but they still can be 'stabbed' " + "easily by moving from one place next to them to another.", + "Ci wojownicy z Puszczy walczą egzotyczną bronią, Jeżowym Ostrzem. " + "Ostrza te bronią je przed atakiem z frontu, ale za to możesz ich łatwo 'dźgnąć' " + "poprzez przejście z jednego pola sąsiadującego z nimi na inne.") + +S("This being radiates an aura of wisdom. " + "It is made of a beautiful crystal, you would love to take it home. " + "But how is it going to defend itself? Better not to think of it, " + "thinking causes your brain to go hot...\n\n" + "Crystal Sages melt at -30 °C, and they can rise the temperature around you from afar.", + "Ta istota promieniuje mądrością. Jest zrobiona z pięknego kryształu, na pewno " + "bardzo cennego. Ciekawe, jak zamierza się przed Tobą bronić? Lepiej o tym nie myśleć, " + "myślenie za bardzo Ciebie rozgrzewa...\n\n" + "Kryształowi Mędrcy topią się w -30 °C, i powodują wzrost temperatury wokół Ciebie.") + +S("Cold white gems, found in the Icy Land.", "Zimne białe kamienie z Krainy Lodu.") + +S("An expensive metal from the Living Caves. For some reason " + "gold prevents the living walls from growing close to it.", + "Drogocenny metal z Żyjących Jaskiń. Złoto utrudnia wzrost ścian wokół niego.") + +S("A rare and expensive substance found in the Desert. " + "It is believed to extend life and raise special psychic powers.", + "Rzadka i droga substancja z Pustyni. Podobno wydłuża życie i daje moce psychiczne.") + +S("A beautiful gem from the Jungle.", "Piękny klejnot z Dżungli.") + +S( + "A wonderful beverage, apparently obtained by mixing red and blue slime. You definitely feel more " + "healthy after drinking it, but you still fell that one hit of a monster is enough to kill you.", + "Cudowny napój, powstały z mieszania czerwonej i niebieskiej mazi. Po jej wypiciu czujesz " + "się zdecydowanie lepiej, ale wciąż jedno uderzenie potwora może Ciebie powalić.") + +S("A piece of a magic mirror, or a mirage cloud, that can be used for magical purposes. Only mirrors and clouds " + "in the Land of Mirrors leave these.", + "Odłamek szkła z magicznego lustra, albo fragment mirażowej chmury. Może zostać użyty do magii. " + "Tylko lustra i chmury z Krainy Luster zostawiają odłamki.") + +S("These sinister totems contain valuable gems.", + "Ten złowieszczy totem zawiera cenne klejnoty.") + +S("These star-shaped flowers native to Hell are a valuable alchemical component.", + "Ta piekielna roślina w kształcie gwiazdy jest cennym składnikiem alchemicznym.") + +S("This statue is made of materials which cannot be found in your world.", + "Ta statua jest zrobiona z materiałów, których nie ma w Twoim świecie.") + +S("One of few things that does not cause the floor in the Land of Eternal Motion to collapse. Obviously they are quite valuable.", + "Pióro Feniksa jest tak lekie, że podłoga z Krainy Wiecznego Ruchu pod nim nie spada. " + "Takie pióra muszą być bardzo cenne.") + +S("Cold blue gems, found in the Cocytus.", "Zimne niebieskie kamienie, znajdowane na zamarźniętym Kocycie.") + +S("These bright yellow gems can be found only by those who have mastered the Crossroads.", + "Te jasne, żółte klejnoty mogą znaleźć tylko mistrze Skrzyżowań.") + +S("That's all you need to unlock the Orb of Yendor! Well... as long as you are able to return to the Orb that this key unlocks...\n\n" + "Each key unlocks only the Orb of Yendor which led you to it.", + "To jest to, czego potrzebujesz, by otworzyć Sferę Yendoru! O ile umiesz do niej trafić...\n" + "Każdy klucz otwiera tylko jedną Sferę, która Ciebie do niego doprowadziła.") + +S("These orbs can be found in the Graveyard. You think that they were once powerful magical orbs, but by now, their " + "power is long gone. No way to use them, you could as well simply drop them...\n\n", + "Na cmentarzu jest mnóstwo tych sfer. Chyba były to kiedyś potężne magiczne kule, ale ich " + "moc dawno przeminęła. Nie ma jak ich użyć, także może lepiej je po prostu zostawić...\n\n") + +S( + "This wonderful Orb can only be collected by those who have truly mastered this hyperbolic universe, " + "as you need the right key to unlock it. Luckily, your psychic abilities will let you know " + "where the key is after you touch the Orb.", + "Ta cudowna sfera może być zdobyta tylko przez prawdziwych mistrzów tego świata. " + "By ją otworzyć, potrzebujesz klucza. Na szczęście Twoje moce psychiczne powiedzą Ci, " + "gdzie jest klucz, gdy dotkniesz Sfery.") + +S( + "This orb can be used to invoke the lightning spell, which causes lightning bolts to shoot from you in all directions.", + "Ta sfera pozwala rzucić czar Błyskawica, który powoduje wystrzelenie błyskawicy w każdym kierunku.") + +S("This orb can be used to invoke a flash spell, which destroys almost everything in radius of 2.", + "Ta sfera pozwala rzucić czar Błysk, który niszczy wszystko w promieniu 2.") + +S("This orb can be used to invoke a wall of ice. It also protects you from fires.", + "Ta sfera zostawia za Tobą ścianę lodu, a także chroni Ciebie przed ogniem.") + +S("This orb can be used to move faster for some time.", + "Ta sfera powoduje, że przez pewien czas poruszasz się szybciej.") + +S("This orb can be used to summon friendly golems. It is used instantly when you pick it up.", + "Ta sfera przywołuje przyjazne golemy. Jest natychmiast używana w momencie podniesienia.") + +S("This orb can protect you from damage.", "Ta sfera chroni Ciebie przed obrażeniami od potworów.") + +S("This orb lets you instantly move to another location on the map. Just click a location which " + "is not next to you to teleport there. ", + "Ta sfera pozwala Ci natychmiast przenieść się do innego miejsca na mapie. Wystarczy " + "kliknąć pole, które nie jest obok Ciebie.") + +S("This orb lets you instantly move to a safe faraway location. Knowing the nature of this strange world, you doubt " + "that you will ever find the way back...\n\n" + "Your game will be saved if you quit the game while the Orb of Safety is still powered.\n\n" + "Technical note: as it is virtually impossible to return, this Orb recycles memory used for the world so far (even if you do not use it to save the game). ", + "Ta sfera pozwala Ci natychmiast przenieść się do bezpiecznego miejsca. Znając naturę tego " + "świata, zapewne nigdy nie trafisz z powrotem...\n\n" + "Jeśli wyjdziesz z gry podczas gdy Sfera Bezpieczeństwa wciąż ma moc, gra zostanie zapisana.\n\n" + "Uwaga techniczna: nawet jeśli nie zapiszesz gry, ta sfera czyści całą pamięć o świecie gry. ") + +S("This orb allows attacking Hedgehog Warriors directly, as well as stabbing other monsters.\n", + "Ta sfera pozwala bezpośrednio atakować Wojowników-Jeże, a także dźgać pozostałych przeciwników.\n") + +S("This flower brings fortune to the person who finds it.\n", + "Ta roślina daje szczęście temu, kto je znajdzie.\n") + +S("Ice Walls melt after some time has passed.", "Lodowe ściany topią się po pewnym czasie.") + +S("A natural terrain feature of the Desert.", "Naturalny teren z Pustyni.") + +S("You can go inside the Magic Mirror, and produce some mirror images to help you.", + "Możesz wejść w Magiczne Lustro, by Twoje odbicia z niego wyszły i Ci pomogły.") + +S( + "Tiny droplets of magical water. You see images of yourself inside them. " + "Go inside the cloud, to make these images help you.", + "Malutkie kropelki magicznej wody, w których widać Twój obraz. Wejdź do środka chmury, " + "by te obrazy Ci pomogły.") + +S("A device that attracts sandworms and other enemies. You need to activate it.", + "To urządzenie przyciąga czerwie i innych przeciwników. Musisz je aktywować.") + +S("A heap of wood that can be used to start a fire. Everything is already here, you just need to touch it to fire it.", + "Stos drewna. Wszystko gotowe, wystarczy podpalić.") + +S("An ancient grave.", "Stary grób.") + +S("A fresh grave. Necromancers like those.", "Świeży grób. Nekromanci to lubią.") + +S("A piece of architecture typical to R'Lyeh.", "Architektura typowa dla R'Lyeh.") + +S("An impassable lake in Cocytus.", "Nie możesz przejść przez Jezioro Kocyt.") + +S("You can walk on it... but beware.", "Możesz tu przejść, ale uważaj!") + +S("It was a floor... until something walked on it.", "Tu kiedyś była podłoga, ale coś po niej przeszło.") + +S( + "This land is a quick gateway to other lands. It is very easy to find other lands " + "from the Crossroads. Which means that you find monsters from most other lands here!\n\n" + "As long as you have found enough treasure in their native lands, you can " + "find magical items in the Crossroads. Mirror Land brings mirrors and clouds, " + "and other land types bring magical orbs.\n\n" + "A special treasure, Hyperstone, can be found on the Crossroads, but only " + "after you have found 10 of every other treasure.", + "Ta kraina jest szybkim przejściem do pozostałych krain. Bardzo łatwo dostać się " + "stąd do pozostałych krain. Również potwory z tych krain łatwo tutaj wejdą!\n\n" + "Możesz znaleźć magiczne przedmioty na Skrzyżowaniu, jeśli zdoby%łeś0 wystarczająco " + "wiele skarbów w ich rodzinnych krainach. Są to sfery, magiczne lustra i chmury.\n\n" + "Specyficzne skarby Skrzyżowań, Hiperkamienie, można znaleźć na Skrzyżowaniu, ale tylko " + "po znalezieniu 10 jednostek każdego innego skarbu.") + +S("A hot land, full of sand dunes, mysterious Spice, and huge and dangerous sand worms.", + "Gorąca ziemia, pełna wydm, tajemniczej Przyprawy, i wielkich Pustynnych Czerwi.") + +S( + "A very cold land, full of ice walls. Your mere presence will cause these ice walls to " + "melt, even if you don't want it.", + "Bardzo zimna kraina, pełna lodowych ścian. Wystarczy Twoja obecność, by te ściany " + "się roztopiły. Nawet, jak tego nie chcesz.") + +S("A land filled with huge ivy plants and dangerous animals.", + "Kraina pełna wielkiego pnącego bluszczu i niebezpiecznych bestii.") + +S("A strange land which contains mirrors and mirages, protected by Mirror Rangers.", + "Dziwna kraina, gdzie można znaleźć magiczne lustra i chmury, bronione przez " + "Strażników Luster.") + +S("All the monsters you kill are carried to this strange land, and buried. " + "Careless Rogues are also carried here...", + "Pochowane są tu wszystkie potwory, które zabijasz. A także poszukiwacze skarbów, którzy " + "nie uważali...") + +S("An ancient sunken city which can be reached only when the stars are right.\n\n" + "You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Prastare zatopione miasto, do którego można dostać się tylko, gdy gwiazdy są " + "na swoich miejscach.\n\n" + "Po znalezieniu 5 Statuetek Cthulhu możesz w R'Lyeh trafić na Świątynie Cthulhu.") + +S("A land filled with demons and molten sulphur. Abandon all hope ye who enter here!", + "Kraina pełna demonów i stopionej siarki. Ty, który wchodzisz, żegnaj się z nadzieją!") + +S("This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.", + "Zamarznięte jezioro. Piekielna wersja Krainy Lodu, w której ciepło Twojego ciała topi ziemię pod Tobą, a nie " + "ściany.") + +S("A land where you cannot stop, because every piece of floor is extremely unstable. Only monsters who " + "can run forever are able to survive there, and only phoenix feathers are so light that they do not disturb " + "the floor.\n", + "Kraina, w której nie możesz przestać się ruszać, bo każdy fragment podłogi jest bardzo niestabilna. " + "Jedynie stworzenia będące w stanie wiecznie się ruszać mogą tu przeżyć, i jedynie pióra feniksa " + "są na tyle lekkie, by nie zaburzyć podłogi.") + +S("Affects looks and grammar", "Wpływa na wygląd i gramatykę") + +S("first joystick: movement threshold", "dżojstik 1: próg ruchu") +S("first joystick: execute movement threshold", "dżojstik 1: próg wykonania ruchu") +S("second joystick: pan threshold", "dżojstik 2: próg przewijania") +S("second joystick: panning speed", "dżojstik 2: prędkość przewijania") +S("%The1 is frozen!", "%1 zamarzł%oa1!") +S("%The1 burns!", "%1 się spalił%oa1!") +S("message flash time", "czas pokazywania wiadomości") + +S("skin color", "kolor skóry") +S("weapon color", "kolor broni") +S("hair color", "kolor włosów") +S("dress color", "kolor sukienki") +S("Shift=random, Ctrl=mix", "Shift=losowo, Ctrl=miks") + +S("Euclidean mode", "tryb euklidesowy") +S("Return to the hyperbolic world", "powrót na hiperboloidę") +S("Choose from the lands visited this game.", "Wybierz spośród odwiedzonych krain.") +S("Scores and achievements are not", "Wyniki i osiągnięcia nie są"); +S("saved in the Euclidean mode!", "zapamiętywane w tym trybie!"); + +// Android buttons (some are not translated because there are no good short words in Polish) +S("MOVE", "RUCH") +S("BACK", "OK") +S("DRAG", "DRAG") +S("INFO", "INFO") +S("MENU", "MENU") +S("QUEST", "MISJA") +S("HELP", "POMOC") +S("NEW", "NOWA") +S("PLAY", "GRAJ") +S("SHARE", "SHARE") +S("HyperRogue for Android", "HyperRogue dla Android") +S("Date: %1 time: %2 s ", "Data: %1 czas: %2 s ") +S("distance: %1\n", "odległość: %1\n") +S("Cheats: ", "Oszustwa: ") +S("Score: ", "Wynik: ") +S("Kills: ", "Zabicia: ") +S("Retrieving scores from Google Leaderboards...", "Ściągam wyniki z rankingów Google...") +S("Scores retrieved.", "Wyniki ściągnięte.") + +S("Your total treasure has been recorded in the Google Leaderboards.", "Twój wynik został zapisany w rankingach Google.") +S("You have improved your total high score on Google. Congratulations!", "Poprawi%łeś0 swój ogólny najlepszy wynik na Google. Gratulacje!") +S("You have improved your '%1' high score on Google!", "Poprawi%łeś0 swój wynik w kategorii '%P1' na Google!") +S("This has been recorded in the Google Leaderboards.", "To zostało zapisane w Rankingach Google.") + +// this text changed a bit: + +S("Ever wondered how some boardgame would look on the hyperbolic plane? " + "I wondered about Go, so I have created this feature. Now you can try yourself!\n" + "Enter = pick up an item (and score), space = clear an item\n" + "Other keys place orbs and terrain features of various kinds\n" + "In the periodic editor, press 0-4 to switch walls in different ways\n", + "Zastanawia%łeś0 się może, jak jakaś gra planszowa wyglądałaby na płaszczyźnie " + "hiperbolicznej? Ja się zastanawiałem nad Go, i postanowiłem to sprawdzić. Teraz " + "Ty też możesz sprawdzić!\n" + "Enter = podnieś przedmiot, space = zabierz przedmiot\n" + "Pozostałe klawisze kładą różnego rodzaju przedmioty\n" + "W edytorze okresowym, klawisze 0-4 zmieniają ściany na różne sposoby") + +S("Periodic Editor", "Edytor okresowy") +// also translate this line: +// "In the periodic editor, press 0-4 to switch walls in different ways\n", + +S("Collect 60 $$$ to access even more lands", "Znajdź 60 $$$ by iść do kolejnych krain") + +// Emerald Mine + +N("Emerald Mine", GEN_F, "Kopalnia Szmaragdów", "Kopalnie Szmaragdów", "Kopalnię Szmaragdów", "w Kopalni Szmaragdów") +N("Pikeman", GEN_M, "Pikinier", "Pikinierzy", "Pikiniera", "Pikinierem") +N("Flail Guard", GEN_M, "Strażnik z cepem", "Strażnicy z cepami", "Strażnika z cepem", "Strażnikiem z cepem") +N("Miner", GEN_M, "Górnik", "Górnicy", "Górnika", "Górnikiem") +N("Emerald", GEN_O, "Szmaragd", "Szmaragdy", "Szmaragd", "Szmaragdem") + +Orb("the Mind", "Psychiki") + +S( + "Evil people are mining for emeralds in this living cave. " + "It does not grow naturally, but it is dug out in a regular " + "pattern, which is optimal according to the evil engineers.", + "Źli ludzie szukają szmaragdów w tej żywej jaskini. " + "Nie rośnie ona naturalnie -- ludzie wykopują regularne " + "wzory, które, zgodnie z oceną złych inżynierów, są 'optymalne'. ") + +S( + "Miners have special tools for dealing with the Living Cave. " + "When they die, these tools activate, destroying the living cave " + "around them.", + "Górnicy mają specjalne narzędzia do kopania w Żywych Jaskiniach. " + "Kiedy giną, te narzędzia się uruchamiają, powodując, że żywa " + "jaskinia wokół nich obumiera.") + +S( + "When Pikemen move, they attack all cells which are now adjacent to them. " + "Luckily, they can be killed in the same way.\n\n" + "They never move if this would attack their friends.", + "Kiedy Pikinier się rusza, atakuje wszystkie komórki, z którymi sąsiaduje " + "po wykonaniu ruchu. Na szczęście, jego samego można pokonać taką samą " + "metodą.\n\n" + "Pikinier się nie rusza, jeśli by w ten sposób zaatakował przyjaciela.") + +S( + "This guard of the Emerald Mine is wielding a huge flail. " + "You cannot attack him directly, as the flail would still hit you then. " + "Luckily, you have learned a trick: if you step away from him, " + "he will hit himself with the flail!", + + "Ten strażnik Kopalni Szmaragdów jest uzbrojony w wielki cep bojowy. " + "Nie możesz go zaatakować bezpośrednio, bo cep by Ciebie uderzył. " + "Na szczęście, znasz sztuczkę: jak się od niego odsuniesz, " + "strażnik uderzy cepem samego siebie!") + +S("A precious green gem from the Emerald Mines.", "Cenny klejnot z Kopalni Szmaragdów.") + +S("%The1 pierces %the2!", "%1 przebi%ł1 %a2!") + +S("Make him hit himself by walking away from him.", + "Odejdź od niego, by sam się zaatakował.") + +S("This orb allows you to instantly kill a non-adjacent enemy by clicking it. " + "Each use drains 30 charges.", + "Ta sfera pozwala natychmiastowo zabić niesąsiadującego przeciwnika (klikając go). " + "Każde użycie zmniejsza poziom naładowania o 30.") + +S("%The1 is immune to mental blasts!", "%1 jest odporn%y1 na atak psychiczny!") +S("You kill %the1 with a mental blast!", "Zabi%łeś1 %a2 mocą psychiczną!") + +// Vineyard + +N("Vineyard", GEN_F, "Winnica", "Winnice", "Winnicę", "w Winnicy") +N("Vine Beast", GEN_M, "Winny Stwór", "Winne Stwory", "Winnego Stwora", "Winnym Stworem") +N("Vine Spirit", GEN_M, "Winny Duszek", "Winne Duszki", "Winnego Duszka", "Winnym Duszkiem") +N("vine", GEN_F, "winorośl", "winorośle", "winorośl", "winoroślą") +N("partial fire", GEN_M, "częściowy ogień", "częściowe ognie", "częściowy ogień", "częściowym ogniem") +N("Wine", GEN_N, "Wino", "Wina", "Wino", "Winem") + +S( "This cell is partially on fire.", "To pole częściowo się pali.") + +S( + "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n" + "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.", + "Winnica jest wypełniona winoroślami. Bardzo gęsta siatka linii prostych...\n\n" + "Winne Bestie i Duszki zmieniają winorośle w trawę i z powrotem.") + +S("A vine is growing here... but only on a half of the cell. How is that even possible?!" + "Most monsters cannot move from this cell to the cell containing the other half. " + "Vine spirits can move only to the adjacent cells which are also adjacent to the " + "other half.", + "Tu rośnie winorośl... ale tylko na połowie pola. Jak to w ogóle jest możliwe?!" + "Większość stworzeń nie może ruszyć się z tego pola na pole zawierające drugą połowę " + "winorośli. Winne duszki mogą się ruszyć tylko na te sąsiednie pola, które sąsiadują " + "także z drugą połową.") + +S( + "A beast made of vines!\n\n" + "Vine Beasts turn into vines when they dies.", + "Stworzenie zrobione z winorośli!\n\n" + "Winne Stwory zmieniają się w winorośle, gdy giną.") + +S( "A spirit living in the vines!\n\n" + "Vine Spirits destroy the vines when they die.", + "Duch żyjący w winoroślach!\n\n" + "Winne Duszki niszczą winorośle, gdy giną.") + +S("Wine grown under hyperbolic sun would be extremely prized in your home location.", + "Wino uprawiane pod hiperbolicznym słońcem, byłoby bardzo cenne w Twojej " + "krainie.") + +S("This orb allows one to pass through all kinds of walls and chasms.", + "Ta sfera pozwala przechodzić przez wszelkie ściany i przepaście.") + +S("You cannot attack through the Vine!", + "Nie możesz atakować poprzez winorośl!") + +Orb("Aether", "Eteru") + +// Dead Caves + +N("Dead Cave", GEN_F, "Martwa Jaskinia", "Martwe Jaskinie", "Martwą Jaskinię", "w Martwej Jaskini") +N("Dark Troll", GEN_M, "Mroczny Troll", "Mroczne Trolle", "Mrocznego Trolla", "Mrocznym Trollem") +N("Earth Elemental", GEN_M, "Żywiołak", "Żywiołaki", "Żywiołaka", "Żywiołakiem") +N("dead wall", GEN_F, "martwa ściana", "martwe ściany", "martwą ścianę", "martwą ścianą") +N("dead floor", GEN_F, "martwa ziemia", "martwe ziemie", "martwą ziemię", "martwą ziemią") +N("rubble", GEN_O, "gruz", "gruzy", "gruz", "gruzem") +N("Silver", GEN_N, "Srebro", "Srebra", "Srebro", "Srebrem") + +S("A precious metal from the Dead Caves.", "Drogocenny metal z Martwej Jaskini.") + +S( "A Troll without the power of Life.", "Troll bez mocy Życia.") + +S( + "A rare unliving construct from the Dead Caves. " + "It instantly destroys cave walls next to its path, and also leaves " + "an impassable wall behind it. You suppose that this impassable wall helps it to " + "escape from some threats. You hope you won't meet these threats...", + + "Rzadka konstrukcja z Martwych Jaskiń. " + "Natychmiast niszczy skalne ściany przy jego trasie, i tworzy " + "za sobą ścianę skały. Przypuszczasz, że ta ściana pomaga mu " + "uciekać przed jakimiś zagrożeniami. Masz nadzieję, że nie spotkasz tych " + "zagrożeń...") + +S("%The1 punches %the2!", "%1 uderzy%ł1 %a2!") +S("%The1 is destroyed by the forces of Life!", "Siły Życia zniszczyły %a1!") +S( "Somehow, this cave has not received the spark of Life yet.", + "Dziwnym trafem, ta jaskinia jeszcze nie zdobyła iskry Życia.") + +// Hive +N("Hive", GEN_N, "Mrowisko", "Mrowiska", "Mrowisko", "w Mrowisku") +N("Red Hyperbug", GEN_M, "Czerwony Hiperinsekt", "Czerwone Hiperinsekty", "Czerwonego Hiperinsekta", "Czerwonym Hiperinsektem") +N("Green Hyperbug", GEN_M, "Zielony Hiperinsekt", "Zielone Hiperinsekty", "Zielonego Hiperinsekta", "Zielonym Hiperinsektem") +N("Blue Hyperbug", GEN_M, "Niebieski Hiperinsekt", "Niebieskie Hiperinsekty", "Niebieskiego Hiperinsekta", "Niebieskim Hiperinsektem") +N("Royal Jelly", GEN_N, "Królewskie Mleczko", "Królewskie Mleczka", "Królewskiego Mleczka", "Królewskim Mleczkiem") +N("weird rock", GEN_N, "dziwna skała", "dziwne skały", "dziwną skałę", "dziwną skałą") + +Orb("Invisibility", "Niewidzialności") + +S("A weirdly colored rock. Hyperentomologists claim that the " + "Hyperbug armies use these rocks to navigate back home after a victorious battle.", + "Ta skała ma dziwny kolor. Hiperentomolodzy twierdzą, że roje Hiperinsektów " + "używają tych skał do nawigacji, by wrócić do domu po wygranej bitwie.") + +S("%The1 fights with %the2!", "%1 zaatakował %a2!") + +S("The Hive is filled with Hyperbugs. They are huge insects which look a bit like " + "ants, a bit like bees, and a bit like roaches. " + "They live in circular nests, and an army of Hyperbugs will attack any intruder, " + "including you and enemy Hyperbugs. Will you manage to get to the " + "heart of such a nest, and get the precious Royal Jelly?", + "Mrowisko jest wypełnione Hiperinsektami. Te wielkie owady wyglądają trochę jak " + "mrówki, trochę jak pszczoły, trochę jak karaluchy. Żyją w okrągłych gniazdach, " + "i atakują każdego najeźdźcę, łącznie z Tobą i wrogimi hiperinsektami. " + "Czy uda Ci się dotrzeć do serca roju, i zdobyć cenne królewskie mleczko?") + +S("This is what Hyperbug Queens eat. Very tasty and healthy.", + "Pożywienie Królowej Hiperinsektów, bardzo smaczne i zdrowe.") + +S("When you have this Orb, most monsters won't see you, unless " + "you are standing still, attacking, or picking up items.", + "Kiedy masz Sferę Niewidzialności, większość potworów Ciebie nie widzi, " + "chyba że stoisz w miejscu, atakujesz, albo podnosisz przedmioty.") + +Orb("Earth", "Ziemi") + +S("This orb lets you go through living walls. It also has powers in some of the other lands.", + "Ta sfera pozwala Ci przechodzić przez żywą ścianę. Ma też moce w niektórych z pozostałych krain.") + +// Land of Power + +N("Land of Power", GEN_F, "Kraina Mocy", "Krainy Mocy", "Krainą Mocy", "w Krainie Mocy") +N("Witch Apprentice", GEN_F, "Uczennica", "Uczennice", "Uczennicę", "Uczennicą") +N("Speed Witch", GEN_F, "Czarownica Szybka", "Czarownice Szybkie", "Czarownicę Szybką", "Czarownicą Szybką") +N("Flash Witch", GEN_F, "Czarownica Błysku", "Czarownice Błysku", "Czarownicę Błysku", "Czarownicą Błysku") +N("Fire Witch", GEN_F, "Czarownica Ognia", "Czarownice Ognia", "Czarownicę Ognia", "Czarownicą Ognia") +N("Aether Witch", GEN_F, "Czarownica Eteru", "Czarownice Eteru", "Czarownicę Eteru", "Czarownicą Eteru") +N("Winter Witch", GEN_F, "Czarownica Zimy", "Czarownice Zimy", "Czarownicę Zimy", "Czarownicą Zimy") +N("Evil Golem", GEN_M, "Zły Golem", "Złe Golemy", "Złego Golema", "Złym Golemem") +N("Powerstone", GEN_M, "Kamień Mocy", "Kamienie Mocy", "Kamień Mocy", "Kamieniem Mocy") +N("crystal cabinet", GEN_F, "kryształowa gablota", "kryształowe gabloty", "kryształową gablotę", "kryształową gablotą") + +S("When you have this Orb, you will leave a trail of fire behind you.", + "Kiedy masz Sferę Ognia, zostawiasz za sobą ognistą ścieżkę.") + +S( + "A Witch without any special powers. But watch out! She will " + "pick up any basic Orbs on her path, and use their powers.", + "Czarownica bez specjalnych mocy. Uważaj! Może ona podnieść " + "dowolną podstawową Sferę na swojej drodze, i użyć jej mocy.") + +S( "A Witch with a Speed spell. She moves twice as fast as you. Unless you " + "have an Orb of Speed too, of course!", + "Czarownica z czarem Szybkości. Rusza się dwa razy szybciej od Ciebie. " + "Chyba że Ty też masz Sferę Szybkości!") + +S( "A Witch with a Fire spell. She will leave a trail of fire behind her.", + "Czarownica z czarem Ogień. Zostawia za sobą płonącą ścieżkę.") + +S( "A Witch with a Winter spell. She is able to move through fire.", + "Czarownica z czarem Zima. Może przechodzić przez ogień.") + +S( "A Witch with an Aether spell. She is able to move through fire and walls.", + "Czarownica z czarem Eter. Może przechodzić przez ogień i ściany.") + +S( "Somebody has summoned these evil constructs with a magical process.", + "Wroga konstrukcja, tworzona poprzez magiczny proces.") + +S( "The Land of Power is filled with everburning fire, magical Orbs, and guarded by " + "witches and golems. There are basic orbs lying everywhere, and more prized ones " + "are kept in crystal cabinets.\n\n" + "Witches are allowed to use all the powers of the " + "basic orbs against intruders. These powers never expire, but a Witch " + "can use only one power at a time (not counting Orbs of Life).\n\n" + "Witches and Golems don't pursue you into other Lands. Also, most Orb powers" + "are drained when you leave the Land of Power.", + "Kraina Mocy jest wypełniona wiecznie płonącym ogniem, magicznymi Sferami, " + "i strzeżona przez Czarownice i golemy. Podstawowe Sfery walają się wszędzie, a " + "te bardziej cenne są trzymane w kryształowych gablotach.\n\n" + "Czarownice używają wszystkich mocy podstawowych Sfer przeciwko intruzom. " + "Ich moce nigdy nie przemijają, ale Czarownica może używać naraz tylko jednej " + "mocy (nie licząc Sfer Życia).\n\n" + "Czarownice i Golemy nie gonią Ciebie do innych krain. Większość Sfer " + "traci swoją moc, gdy opuszczasz Krainę Mocy.") + +S( + "Witches use these crystal cabinets to protect Powerstones, as well as the more " + "expensive Orbs. They are partially protected from thieves: they are too strong " + "to be smashed by conventional attacks, and if you try to steal the item " + "using an Orb of Aether, your Aether power will be completely drained.", + "Czarownice używają tych kryształowych gablot, by chronić Kamienie Mocy oraz bardziej " + "cenne Sfery. Gabloty są częściowo chronione przed kradzieżą: są zbyt mocne, " + "by je rozbić konwencjonalnymi atakami, a jeśli spróbujesz ukraść przedmiot " + "używając Sfery Eteru, Twoja moc Eteru zostanie całkowicie wyczerpana.") + +S( + "A Stone from the Land of Power. You are not sure what it is exactly, but " + "as the Powerstones are kept in crystal cabinets, they are surely valuable.", + "Kamień z Krainy Mocy. W sumie to nie wiesz, co to jest, ale trzymają te " + "kamienie w kryształowych gablotach, także musi być bardzo cenny.") + +Orb("Fire", "Ognia") + +// achievements: + +// x "Head Witch", "Have 10 Orbs active at the same time." +// "Enemy Number One", "Have an army of 1000 hyperbugs pursue you." +// x "Lifebringer", "Brought Life into the Dead Caves." +// "Wall Gardener", "Make a living wall grow outside of a cavernous region." +// x "Master Swordsman", "Defeat a Hedgehog Warrior, a Pikeman, and a Flail Guard at the same time." +// x "Master of Melee", "Defeat five monsters in melee at the same time." + +// for collection achievements: +// provide the required cases for descriptions: +// Spice, Royal Jelly, Silver, Powerstone, and Wine +// achievement names: +// Master of the Hive, Master of Power, Master of Vineyard, Master of Dead Caves, Master of the Mine +// "Hyperbug", "Hyperbug Warrior", "Hyperbug Queen", + +// for the store description: + +// (currently, five more lands are included!) + +// lines forgotten previously + +S("Your Aether power has expired! RUN!", "Twoja moc Eteru się wyczerpała! UCIEKAJ!") + +S("%The1 tricks %the2.", "%1 pokona%ł1 %a2.") +S("You trick %the1.", "Pokona%łeś0 %a1.") + +S( "A Witch with a Flash spell. Very dangerous!\n\nLuckily, she never uses the spell if it " + "would kill her friends. She could destroy an Evil Golem, though.", + "Czarownica z czarem Błysk. Bardzo niebezpieczna!\n\nNa szczęście, nie użyje swojego " + "czaru, jeśli by to zabiło jej przyjaciółki.") + +S("Your Aether powers are drained by %the1!", "Twoja moc Eteru została wyssana przez %a1!") +S("As you leave, your powers are drained!", "Opuszczasz Krainę Mocy... Twoja moc znikła!") +S("%The1 picks up %the2!", "%1 podniosła %a2!") // currently only Witches, so only female form + +S("You can right click any element to get more information about it.\n\n", + "Kliknij obiekt prawym przyciskiem myszy, by zobaczyć więcej informacji na jego temat.\n\n") + +S("TRANSLATIONWARNING", "") + +S("The Hyperbugs are fighting!", "Hiperinsekty ze sobą walczą!") + +S("","") N("",GEN_N,"","","","") + +S("Cheat-changed the display.", "Zmieniam tryb wyświetlania.") +S("Dead floor, with some rubble.", "Martwa ziemia, jest tu trochę gruzu.") + +// Camelot + +N("Camelot", GEN_O, "Camelot", "Camelot", "Camelot", "w Camelot") +N("wall of Camelot", GEN_F, "ściana Camelot", "ściany Camelot", "ścianę Camelot", "ścianą Camelot") +N("moat of Camelot", GEN_F, "fosa Camelot", "fosy Camelot", "fosę Camelot", "fosą Camelot") +N("Round Table", GEN_O, "Okrągły Stół", "Okrągłe Stoły", "Okrągły Stół", "Okrągłym Stołem") +N("Knight", GEN_M, "Rycerz", "Rycerze", "Rycerza", "Rycerzem") +N("Holy Grail", GEN_M, "Święty Graal", "Święte Graale", "Świętego Graala", "Świętym Graalem") + +S( + "The Knights of the Round Table are the greatest warriors of these lands. " + "They are not very inventive with names though, as they call each of their " + "castles Camelot. " + "You are probably worth of joining them, but they will surely give you " + "some quest to prove yourself...\n\n" + "Each castle contains a single treasure, the Holy Grail, in the center. " + "The radius of the Round Table is usually 28, but after you find a Holy Grail " + "successfully, each new castle (and each Round Table) you find will be bigger.", + + "Rycerze Okrągłego Stołu to najwięksi wojownicy tych krain. Niestety, nie są " + "zbyt pomysłowi w nazywaniu, i każdy swój zamek nazywają Camelot. " + "Prawdopodobnie nadajesz się, by stać się jednym z nich, ale na pewno " + "dadzą Ci jakąś misję, byś pokaza%ł0 swoją wartość...\n\n" + "Każdy zamek ma jeden skarb (Święty Graal) w samym środku. Promień Okrągłego " + "Stołu to normalnie 28, ale z każdym znalezionym Śwętym Graalem każdy nowy " + "zamek (i jego Okrągły Stół) będzie większy.") + +S("It would be impolite to land on the table!", + "Byłoby niegrzecznie wylądować na stole!") +S("You jump over the table!", "Skaczesz przez stół!") +S("That was not a challenge. Find a larger castle!", + "To nie było wyzwanie. Znajdź większy zamek!") +S("The Knights congratulate you on your success!", + "Rycerze gratulują Ci sukcesu!") +S("The Knights laugh at your failure!", + "Rycerze śmieją się z Twojej porażki!") +S("The Knights stare at you!", "Rycerze gapią się na Ciebie ze zdziwieniem!") +S("Come on, this is too easy... find a bigger castle!", + "Eee, to będzie za łatwe... znajdź większy zamek!") +S("The Knights wish you luck!", "Rycerze życzą powodzenia!") + +S("Congratulations! You have found the Holy Grail!", + "Gratulacje! Znalaz%łeś0 Świętego Graala!") + +S("\"I would like to congratulate you again!\"", "\"Pragnę jeszcze raz Ci pogratulować!\"") +S("\"Find the Holy Grail to become one of us!\"", "\"Znajdź Świętego Graala, by stać się jednym z nas!\"") +S("\"The Holy Grail is in the center of the Round Table.\"", "\"Święty Graal jest pośrodku Okrągłego Stołu.\"") +S("\"I enjoy watching the hyperbug battles.\"", "\"Lubię oglądać bitwy hiperinsektów.\"") +S("\"Have you visited a temple in R'Lyeh?\"", "\"By%łeś0 w świątyni w R'Lyeh?\"") +S("\"Nice castle, eh?\"", "\"Ładny zamek, co?\"") + +// Temple + +N("Temple of Cthulhu", GEN_F, "Świątynia Cthulhu", "Świątynie Cthulhu", "Świątynię Cthulhu", "w Świątyni Cthulhu") +N("big statue of Cthulhu", GEN_O, "pomnik Cthulhu", "pomniki Cthulhu", "pomnik Cthulhu", "pomnikiem Cthulhu") +N("Grimoire", GEN_F, "Księga", "Księgi", "Księgę", "Księgą") +N("Cult Leader", GEN_M, "Przywódca Kultu", "Przywódcy Kultu", "Przywódcę Kultu", "Przywódcą Kultu") + +S("The temple of Cthulhu consists of many concentric circles of columns. " + "You will surely encounter many Cultists there, who believe that a pilgrimage " + "to the inner circles will bring them closer to Cthulhu himself, and Grimoires " + "which surely contain many interesting secrets.\n\n" + "The circles in the temple of Cthulhu are actually horocycles. They are " + "infinite, and there is an infinite number of them.", + + "Świątynia Cthulhu składa się z wielu koncentrycznych kręgów kolumn. " + "Spotkasz tu wielu Kultystów, dla których pielgrzymka do wewnętrznych kręgów " + "to szansa na bycie bliżej Cthulhu, i Księgi zawierające wiele interesujących " + "sekretów.\n\n" + "Kręgi w Świątyni Cthulhu są właściwie horocyklami. Są nieskończone, i " + "jest ich nieskończenie wiele." + ) + +S("The Grimoires contain many secrets of the Great Old Ones. " + "Each new inner circle in the Temple of Cthulhu contains new Grimoires, with new secrets. " + "You hope to read them when you return home, and to learn many things. " + "The knowledge is valuable to you, but it is rather pointless to try to get " + "several copies of the same Grimoire...", + "Te Księgi zawierają tajemnice Wielkich Przedwiecznych. " + "Każdy krąg wewnętrzny w Świątyni Cthulhu zawiera nowe Księgi, z nowymi sekretami. " + "Zamierzasz je przeczytać po powrocie do domu. Wiedza jest dla Ciebe wartościowa, " + "ale nie ma sensu, by brać kilka kopii tej samej Księgi..." + ) + +S("These statues of Cthulhu are too large to carry, and they don't look too " + "valuable anyway. Most monsters will never go through them... they probably have " + "their reasons. But you can go! When you move into the cell containing " + "a statue, you push the statue to the cell you left.\n", + + "Te pomniki Cthulhu są za duże, by je nosić, zresztą i tak nie wyglądają " + "na zbyt cenne. Potwory nigdy przez nie nie przechodzą... pewnie mają swoje " + "powody. Ale Ty możesz przejść! Kiedy wchodzisz na pole z pomnikiem, " + "automatycznie przesuwasz pomnik na pole, które opuści%łeś0." + ) + +S("These Cultists can push the statues, just like you.", + "Ci kultyści mogą przesuwać pomniki, tak samo jak Ty.") + +S("You already have this Grimoire! Seek new tomes in the inner circles.", + "Już masz taką Księgę! Szukaj nowych tomów w wewnętrznych kręgach.") + +S("You push %the1 behind you!", "Popchn%ąłeś0 %a1 za siebie.") + +// More texts + +S("Your total kills", "Łączne zabicia") + +S( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count.", + + "W większości krain, zabijanie przeciwników pochodzących z danej krainy " + "powoduje, że generowane jest więcej skarbów. Ponadto, 100 zabić jest konieczne, " + "by móc znaleźć Cmentarz i Mrowisko.\n\n" + "Przyjazne stworzenia i części potworów (jak np. Bluszcz) występują na liście, " + "ale nie są liczone do łącznej liczby zabić.") + +S("There must be some temples of Cthulhu in R'Lyeh...", + "Muszą być jakieś świątynie Cthulhu w R'Lyeh...") + +S("You overheard Hedgehog Warriors talking about emeralds...", + "Podsłucha%łeś0 Jeże rozmawiające o szmaragdach...") + +S("You overhear miners talking about a castle...", + "Podsłucha%łeś0 górników rozmawiających o zamku...") + +S("A castle in the Crossroads...", "O zamku na Skrzyżowaniu...") + +/* +S("You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Po znalezieniu 5 Statuetek Cthulhu możesz w R'Lyeh trafić na Świątynie Cthulhu.") +*/ + +S("You have to escape first!", "Musisz najpierw uciec!"); +S("There is not enough space!", "Nie ma miejsca!"); + +S("Customize character", "pokoloruj postać") +S("gender", "płeć") + +// + +Orb("the Dragon", "Smoka") + +S("This Orb allows you to throw fire, just like the Fire Cultists.\n\n" + "Each fire drains 5 charges. You are not allowed to throw fire into adjacent cells.", + "Ta sfera pozwala Ci rzucać ogniem, tak jak Ogniści Kultyści. \n\n" + "Każdy rzucony ogień wymaga 5 ładunków. Nie możesz rzucać ogniem do sąsidenich " + "komórek." + ) + +S("You throw fire!", "Rzucasz ogniem!") + +Orb("Trickery", "Sztuczek") + +N("Illusion", GEN_F, "Iluzja", "Iluzje", "Iluzję", "Iluzją") + +S("This Orb allows you to create illusions of yourself. Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.\n\n" + "Each illusion takes 5 charges to create, and one extra charge " + "per turn. You can also click your illusion to take it away, restoring 4 charges.\n\n" + "If you have both Orb of Teleport and Orb of Trickery, Illusion is cast " + "first -- you can then teleport on your Illusion to switch places with it.", + "Ta sfera pozwala Ci tworzyć iluzje samego siebie. Większość potworów celuje w " + "iluzje, podobnie jak w Ciebie, Dudniki i Twoich przyjaciół.\n\n" + "Każda iluzja wymaga 5 ładunków do stworzenia, i jednego dodatkowego ładunku na " + "kolejkę. Możesz też kliknąć swoją iluzję by ją zabrać, co przywraca 4 ładunki.\n\n" + "Jeśli masz zarówno Sferę Teleportacji, jak i Sztuczek, Iluzja rzucana jest " + "jako pierwsza -- możesz następnie teleportować się na swoją iluzję, by się z nią " + "zamienić miejscami." + ) + +S("Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.", + "Większość potworów celuje w " + "iluzje, podobnie jak w Ciebie, Dudniki i Twoich przyjaciół.") + +S("You create an Illusion!", "Tworzysz iluzję!") +S("You take the Illusion away.", "Zabierasz iluzję!") + +S("You cannot target that far away!", "Nie możesz celować tak daleko!") +S("You cannot target that close!", "Nie możesz celować tak blisko!") +S("Cannot teleport on a monster!", "Nie możesz teleportować się na potwora!") +S("Cannot teleport on an item!", "Nie możesz teleportować się na przedmiot!") +S("Cannot teleport here!", "Nie możesz teleportować się tutaj!") +S("Cannot cast illusion on an item!", "Nie możesz rzucić iluzji na przedmiot!") +S("Cannot cast illusion here!", "Nie możesz rzucić ilzuji tutaj!") +S("Cannot cast illusion on a monster!", "Nie możesz rzucić ilzuji na potwora!") +S("Cannot throw fire there!", "Nie możesz tego podpalić!") + +// teleport -> target +// You cannot target that close! +#undef Orb + +S("or ESC to see how it ended", "lub ESC by zobaczyć, jak się skończyło") +S("high contrast", "wysoki kontrast") +S("draw the heptagons darker", "siedmiokąty ciemniejsze"); +S("targetting ranged Orbs with Shift+click only", "celowanie zdalne tylko Shift+klik") +S("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.", + "Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, itd.") diff --git a/language-pl.cpp b/language-pl.cpp new file mode 100644 index 00000000..dfd11410 --- /dev/null +++ b/language-pl.cpp @@ -0,0 +1,1480 @@ +// This translation file is encoded with UTF-8 + +// Nouns. + +// For each noun in English, provide: + +// 1) the type (usually gender) of the noun. For example, in Polish each noun can be: + +// masculine living (GEN_M), +// masculine object (GEN_O), +// feminine (GEN_F), or +// neuter (GEN_N). + +// 2) all the forms required by HyperRogue. For example, in Polish the following are +// given: +// The following forms are given: +// nominative (referred to as %1), +// nominative plural (%P1), +// accusative (%a1), +// ablative (%abl1) (for land names, locative "in/on..." is given instead of ablative). + +// Feel free to add more or less forms or types if needed. Note that you don't +// have to provide all the forms in your language, only those used by HyperRogue +// (in Polish just 4 of 14 forms are used, and this is probably similar in other +// languages). + +// monsters +N("Yeti", GEN_M, "Yeti", "Yeti", "Yeti", "Yeti") +N("Icewolf", GEN_M, "Lodowy Wilk", "Lodowe Wilki", "Lodowego Wilka", "Lodowym Wilkiem") +N("Ranger", GEN_M, "Strażnik", "Strażnicy", "Strażnika", "Strażnikiem") +N("Rock Troll", GEN_M, "Skalny Troll", "Skalne Trolle", "Skalnego Trolla", "Skalnym Trollem") +N("Goblin", GEN_M, "Goblin", "Gobliny", "Goblina", "Goblinem") +N("Sand Worm", GEN_M, "Pustynny Czerw", "Pustynne Czerwie", "Pustynnego Czerwia", "Pustynnym Czerwiem") +N("Sand Worm Tail", GEN_M, "Ogon Czerwia", "Ogony Czerwia", "Ogon Czerwia", "Ogonem Czerwia") +N("Sand Worm W", GEN_M, "Pustynny Czerw W", "Pustynne Czerwie W", "Pustynnego Czerwia W", "Pustynnym Czerwiem W") +N("Desert Man", GEN_M, "Człowiek Pustyni", "Ludzie Pustyni", "Człowieka Pustyni", "Człowiekiem Pustyni") +N("Ivy Root", GEN_M, "Korzeń Bluszczu", "Korzenie Bluszczu", "Korzeń Bluszczu", "Korzeniem Bluszczu") +N("Active Ivy", GEN_M, "Aktywny Bluszcz", "Aktywne Bluszcze", "Aktywny Bluszcz", "Aktywnym Bluszczem") +N("Ivy Branch", GEN_F, "Gałąź Bluszczu", "Gałęzie Bluszczu", "Gałąź Bluszczu", "Gałęzią Bluszczu") +N("Dormant Ivy", GEN_M, "Uśpiony Bluszcz", "Uśpione Bluszcze", "Uśpiony Bluszcz", "Uśpionym Bluszczem") +N("Ivy N", GEN_M, "Bluszcz N", "Bluszcze N", "Bluszcz N", "Bluszczem N") +N("Ivy D", GEN_M, "Bluszcz D", "Bluszcze D", "Bluszcz D", "Bluszczem D") +N("Giant Ape", GEN_F, "Wielka Małpa", "Wielkie Małpy", "Wielką Małpę", "Wielką Małpą") +N("Slime Beast", GEN_M, "Mazisty Stwór", "Maziste Stwory", "Mazistego Stwora", "Mazistym Stworem") +N("Mirror Image", GEN_N, "Odbicie Lustrzane", "Odbicia Lustrzane", "Odbicie Lustrzane", "Odbiciem Lustrzanym") +N("Mirage", GEN_M, "Miraż", "Miraże", "Miraż", "Mirażem") +N("Golem", GEN_M, "Golem", "Golemy", "Golema", "Golemem") +N("Eagle", GEN_M, "Orzeł", "Orły", "Orła", "Orłem") +N("Seep", GEN_M, "Sączak", "Sączaki", "Sączaka", "Sączakiem") +N("Zombie", GEN_M, "Zombie", "Zombies", "Zombie", "Zombie") +N("Ghost", GEN_M, "Duch", "Duchy", "Ducha", "Duchem") +N("Necromancer", GEN_M, "Nekromanta", "Nekromanci", "Nekromantę", "Nekromantą") +N("Shadow", GEN_M, "Cień", "Cienie", "Cień", "Cieniem") +N("Tentacle", GEN_F, "Macka", "Macki", "Mackę", "Macką") +N("Tentacle Tail", GEN_F, "Ogon Macki", "Ogony Macki", "Ogon Macki", "Ogonem Macki") +N("Tentacle W", GEN_F, "Macka W", "Macki W", "Mackę W", "Macką W") +N("Tentacle (withdrawing)", GEN_F, "Macka (uciekająca)", "Macki (uciekające)", "Mackę (uciekającą)", "Macką (uciekającą") +N("Cultist", GEN_M, "Kultysta", "Kultyści", "Kultystę", "Kultystą") +N("Fire Cultist", GEN_M, "Ognisty Kultysta", "Ogniści Kultyści", "Ognistego Kultystę", "Ognistym Kultystą") +N("Greater Demon", GEN_M, "Wielki Demon", "Wielkie Demony", "Wielkiego Demona", "Wielkim Demonem") +N("Lesser Demon", GEN_M, "Mniejszy Demon", "Mniejsze Demony", "Mniejszego Demona", "Mniejszym Demonem") +N("Ice Shark", GEN_M, "Lodowy Rekin", "Lodowe Rekiny", "Lodowego Rekina", "Lodowym Rekinem") +N("Running Dog", GEN_M, "Biegnący Pies", "Biegnące Psy", "Biegnącego Psa", "Biegnącym Psem") +N("Demon Shark", GEN_M, "Rekin-Demon", "Rekiny-Demony", "Rekina-Demona", "Rekinem-Demonem") +N("Fire Fairy", GEN_F, "Ognista Rusałka", "Ogniste Rusałki", "Ognistą Rusałkę", "Ognistą Rusałką") +N("Crystal Sage", GEN_M, "Kryształowy Mędrzec", "Kryształowi Mędrcy", "Kryształowego Mędrca", "Kryształowym Mędrcem") +N("Hedgehog Warrior", GEN_M, "Wojownik-Jeż", "Wojownicy-Jeże", "Wojownika-Jeża", "Wojownikiem-Jeżem") +// items +N("Ice Diamond", GEN_O, "Lodowy Diament", "Lodowe Diamenty", "Lodowy Diament", "Lodowym Diamentem") +N("Gold", GEN_N, "Złoto", "Złota", "Złoto", "Złotem") +N("Spice", GEN_F, "Przyprawa", "Przyprawy", "Przyprawę", "Przyprawą") +N("Ruby", GEN_O, "Rubin", "Rubiny", "Rubin", "Rubinem") +N("Elixir of Life", GEN_O, "Eliksir Życia", "Eliksiry Życia", "Eliksir Życia", "Eliksirem Życia") +N("Shard", GEN_O, "Odłamek", "Odłamki", "Odłamek", "Odłamkiem") +N("Necromancer's Totem", GEN_O, "Totem Nekromanty", "Totemy Nekromanty", "Totem Nekromanty", "Totemem Nekromanty") +N("Demon Daisy", GEN_F, "Czarcie Ziele", "Czarcie Ziela", "Czarcie Ziele", "Czarcim Zielem") +N("Statue of Cthulhu", GEN_F, "Statuetka", "Statuetki", "Statuetkę", "Statuetką") +N("Phoenix Feather", GEN_N, "Pióro Feniksa", "Pióra Feniksa", "Pióro Feniksa", "Piórem Feniksa") +N("Ice Sapphire", GEN_O, "Lodowy Szafir", "Lodowe Szafiry", "Lodowy Szafir", "Lodowym Szafirem") +N("Hyperstone", GEN_O, "Hiperkamień", "Hiperkamienie", "Hiperkamień", "Hiperkamieniem") +N("Key", GEN_O, "Klucz", "Klucze", "Klucz", "Kluczem") +N("Dead Orb", GEN_F, "Martwa Sfera", "Martwe Sfery", "Martwą Sferę", "Martwą Sferą") +N("Fern Flower", GEN_O, "Kwiat Paproci", "Kwiaty Paproci", "Kwiat Paproci", "Kwiatem Paproci") +// orbs: we are using a macro here +#define Orb(E, P) N("Orb of "E, GEN_F, "Sfera "P, "Sfery "P, "Sferę "P, "Sferą "P) +Orb("Yendor", "Yendoru") +Orb("Storms", "Burzy") +Orb("Flash", "Błysku") +Orb("Winter", "Zimy") +Orb("Speed", "Szybkości") +Orb("Life", "Życia") +Orb("Shielding", "Tarczy") +Orb("Teleport", "Teleportacji") +Orb("Safety", "Bezpieczeństwa") +Orb("Thorns", "Cierni") +// terrain features +N("none", GEN_O, "nic", "nic", "niczego", "niczym") +N("ice wall", GEN_F, "lodowa ściana", "lodowe ściany", "lodową ścianę", "lodową ścianą") +N("great wall", GEN_F, "wielka ściana", "wielkie ściany", "wielką ścianę", "wielką ścianą") +N("red slime", GEN_F, "czerwona maź", "czerwone mazie", "czerwoną maź", "czerwoną mazią") +N("blue slime", GEN_F, "niebieska maź", "Niebieskie mazie", "niebieską maź", "niebieską mazią") +N("living wall", GEN_F, "żywa ściana", "żywe ściany", "żywą ścianę", "żywą ścianą") +N("living floor", GEN_F, "żywa ziemia", "żywe ziemie", "żywą ziemię", "żywą ziemią") +N("dead troll", GEN_M, "martwy troll" ,"martwe trolle", "martwego trolla", "martwym trollem") +N("sand dune", GEN_F, "wydma", "wydmy", "wydmę", "wydmą") +N("Magic Mirror", GEN_N, "Magiczne Lustro", "Magiczne Lustra", "Magiczne Lustro", "Magicznym Lustrem") +N("Cloud of Mirage", GEN_F, "Chmura Mirażowa", "Chmury Mirażowe", "Chmurę Mirażową", "Chmurą Mirażową") +N("Thumper", GEN_O, "Dudnik", "Dudniki", "Dudnik", "Dudnikiem") +N("Bonfire", GEN_N, "Ognisko", "Ogniska", "Ognisko", "Ogniskiem") +N("ancient grave", GEN_O, "stary grób", "stare groby", "stary grób", "starym grobem") +N("fresh grave", GEN_O, "świeży grób", "świeże groby", "świeży grób", "świeżym grobem") +N("column", GEN_F, "kolumna", "kolumny", "kolumnę", "kolumną") +N("lake of sulphur", GEN_N, "jezioro siarki", "jeziora siarki", "jezioro siarki", "jeziorem siarki") +N("lake", GEN_N, "jezioro", "jeziora", "jezioro", "jeziorem") +N("frozen lake", GEN_N, "zamarznięte jezioro", "zamarznięte jeziora", "zamarznięte jezioro", "zamarzniętym jeziorem") +N("chasm", GEN_N, "przepaść", "przepaści", "przepaść", "przepaścią") +N("big tree", GEN_N, "duże drzewo", "duże drzewa", "duże drzewo", "dużym drzewem") +N("tree", GEN_N, "drzewo", "drzewo", "drzewo", "drzewem") +// lands +N("Great Wall", GEN_N, "Wielka Ściana", "Wielkie Ściany", "Wielką Ścianę", "na Wielkiej Ścianie") +N("Crossroads", GEN_N, "Skrzyżowanie", "Skrzyżowania", "Skrzyżowanie", "na Skrzyżowaniu") +N("Desert", GEN_F, "Pustynia", "Pustynie", "Pustynię", "na Pustyni") +N("Icy Land", GEN_F, "Lodowa Kraina", "Lodowe Krainy", "Lodową Krainę", "w Lodowej Krainie") +N("Living Cave", GEN_F, "Żywa Jaskinia", "Żywe Jaskinie", "Żywą Jaskinię", "w Żywej Jaskini") +N("Jungle", GEN_F, "Dżungla", "Dżungle", "Dżunglę", "w Dżungli") +N("Alchemist Lab", GEN_N, "Laboratorium", "Laboratoria", "Laboratorium", "w Laboratorium") +N("Mirror Land", GEN_F, "Kraina Luster", "Krainy Luster", "Krainę Luster", "w Krainie Luster") +N("Graveyard", GEN_O, "Cmentarz", "Cmentarze", "Cmentarz", "na Cmentarzu") +N("R'Lyeh", GEN_N, "R'Lyeh", "R'Lyeh", "R'Lyeh", "w R'Lyeh") +N("Hell", GEN_N, "Piekło", "Piekła", "Piekło", "w Piekle") +N("Cocytus", GEN_M, "Kocyt", "Kocyt", "Kocytu", "w Kocycie") +N("Land of Eternal Motion", GEN_N, "Kraina Wiecznego Ruchu", "Krainy Wiecznego Ruchu", "Krainę Wiecznego Ruchu", "w Krainie Wiecznego Ruchu") +N("Dry Forest", GEN_M, "Puszcza", "Puszcze", "Puszczę", "w Puszczy") +N("Game Board", GEN_F, "Plansza", "Plansze", "Planszę", "na Planszy") + +// Game messages + +// fighting messages + +// For each English form, provide a Polish form. Player is referred to via %...0, +// and objects are referred to via %...1 and %...2. For example, in Polish: + +// %a1 refers to the accusative form of the first object (as explained above in 'Nouns') +// likewise, %a2 refers to the accusative form of the second object +// %ł1 is replaced by "ł", "ło" or "ła", depending on the gender of %1 +// %łeś0 adds "łeś" or "łaś" depending on the gender of the player + +// Use whatever %xxx# codes you need for your language. Of course, +// tell me how your codes should be expanded. + +S("You kill %the1.", "Zabi%łeś0 %a1.") +S("You would be killed by %the1!", "Zabi%ł1by Ciebie %1!") +S("%The1 would get you!", "Dopad%ł1by Ciebie %1!") +S("%The1 destroys %the2!", "%1 zniszczy%ł1 %a2!") +S("%The1 eats %the2!", "%1 zjad%ł1 %a2!") +S("The ivy destroys %the1!", "Bluszcz zniszczył %a1!") +S("%The1 claws %the2!", "%1 zaatakowa%ł1 %a2!") +S("%The1 scares %the2!", "%1 wystraszy%ł1 %a2!") +S("%The1 melts away!", "%1 się stopi%ł1!") +S("%The1 stabs %the2.", "%1 dźgn%ął1 %a2.") +S("You stab %the1.", "Dźgn%ąłeś0 %a1.") + +S("You cannot attack %the1 directly!", "Nie możesz atakować %a1 wprost!") +S("Stab them by walking around them.", "Przejdź wokół, by dźgnąć.") + +S("You feel more experienced in demon fighting!", "Jesteś bardziej doświadczony w walce z demonami!") +S("Cthulhu withdraws his tentacle!", "Cthulhu chowa swoją mackę!") +S("The sandworm explodes in a cloud of Spice!", "Czerw eksplodował! Chmura Przyprawy!") +S("%The1 is confused!", "%1 jest zmieszan%ya1.") +S("%The1 raises some undead!", "%1 wzbudza umarłych!") +S("%The1 throws fire at you!", "%1 rzuca w Ciebie ogniem!") +S("%The1 shows you two fingers.", "%1 pokaza%ł1 Ci dwa palce.") +S("You wonder what does it mean?", "Co to może znaczyć?") +S("%The1 shows you a finger.", "%1 pokaza%ł1 Ci palec.") +S("You think about possible meanings.", "Zastanawiasz się nad możliwymi znaczeniami.") +S("%The1 moves his finger downwards.", "%1 przesun%ął1 swój palec w dół.") +S("Your brain is steaming.", "Twój mózg paruje.") +S("%The1 destroys %the2!", "%1 zniszczy%ł1 %a2!") +S("You join %the1.", "Połączy%łeś0 się z %abl1.") +S("Two of your images crash and disappear!", "Dwa Twoje obrazy wpadły na siebie i znikły!") +S("%The1 breaks the mirror!", "%1 rozbi%ł1 lustro!") +S("%The1 disperses the cloud!", "%1 rozprys%ł1 chmurę!") +S("You activate the Flash spell!", "Aktywowa%łeś0 czar Błysk!") +S("You activate the Lightning spell!", "Aktywowa%łeś0 czar Burza!") +S("Ice below you is melting! RUN!", "Lód pod Tobą się topi! UCIEKAJ!") +S("This spot will be burning soon! RUN!", "To się zaraz zapali! UCIEKAJ!") +S("The floor has collapsed! RUN!", "Ziemia się zapadła! UCIEKAJ!") +S("You need to find the right Key to unlock this Orb of Yendor!", + "Potrzebujesz prawidłowego Klucza, by otworzyć Sferę Yendoru!") +S("You fall into a wormhole!", "Wpad%łeś0 w tunel przestrzenny!") +S("You activate %the1.", "Aktywowa%łeś0 %a1.") +S("No room to push %the1.", "Brak miejsca, by popchnąć %a1.") +S("You push %the1.", "Popchn%ąłeś0 %a1.") +S("You start cutting down the tree.", "Zaczynasz ciąć drzewo.") +S("You cut down the tree.", "Ści%ąłeś0 drzewo.") +S("You cannot attack Sandworms directly!", "Nie możesz atakować Czerwi wprost!") +S("You cannot attack Tentacles directly!", "Nie możesz atakować Macek wprost!") +S("You cannot defeat the Shadow!", "Nie możesz pokonać Cienia!") +S("You cannot defeat the Greater Demon yet!", "Nie możesz jeszcze pokonać Wielkiego Demona!") +S("That was easy, but groups could be dangerous.", "To było proste, z grupami może być trudniej.") +S("Good to know that your fighting skills serve you well in this strange world.", "Dobrze wiedzieć, że Twoje zdolności walki przydają się w tym świecie.") +S("You wonder where all these monsters go, after their death...", "Gdzie te wszystkie potwory idą po śmierci?...") +S("You feel that the souls of slain enemies pull you to the Graveyard...", "Czujesz, jak dusze pokonanych wrogów wołają Ciebie na Cmentarz...") +S("Wrong color!", "Zły kolor!") +S("You cannot move through %the1!", "Nie możesz przejść przez %a1!") +S("%The1 would kill you there!", "%1 by Ciebie zabi%ł1!") +S("Wow! %1! This trip should be worth it!", "%1! Ta wyprawa powinna się opłacić!") +S("For now, collect as much treasure as possible...", "Szukaj skarbów, znajdź, ile tylko możesz...") +S("Prove yourself here, then find new lands, with new quests...", "Pokaż, co potrafisz tutaj, potem znajdź nowe krainy i misje...") +S("You collect your first %1!", "Znalaz%łeś0 pierwsz%yą1 %a1!") +S("You have found the Key! Now unlock this Orb of Yendor!", "Znalaz%łeś0 Klucz! Otwórz Sferę Yendoru!") +S("This orb is dead...", "Ta sfera jest martwa...") +S("Another Dead Orb.", "Jeszcze jedna Martwa Sfera.") +S("You have found %the1!", "Znalaz%łeś0 %a1!") +S("You feel that %the2 become%s2 more dangerous.", "Masz wrażenie, że %2 staje się bardziej niebezpieczn%ya2.") +S("With each %1 you collect...", "Z każd%ymą1 %abl1, które znajdujesz...") +S("Are there any magical orbs in %the1?...", "Czy %abl1 są jakieś magiczne sfery?") +S("You feel that %the1 slowly become%s1 dangerous...", "Masz wrażenie, że %1 powoli staje się niebezpieczn%ya1...") +S("Better find some other place.", "Lepiej znajdź inne miejsce.") +S("You have a vision of the future, fighting demons in Hell...", "Masz wizję przyszłości, w której walczysz z demonami w Piekle...") +S("With this Elixir, your life should be long and prosperous...", "Ten Eliksir pozwoli Ci na długie i szczęśliwe życie...") +S("The Necromancer's Totem contains hellish incantations...", "Totem Nekromanty zawiera piekielne inkantacje...") +S("The inscriptions on the Statue of Cthulhu point you toward your destiny...", "Inskrypcje na Statui Cthulhu wskazują Ci Twoje Przeznaczenie...") +S("Still, even greater treasures lie ahead...", "Jeszcze większe skarby przed Tobą...") +S("You collect %the1.", "Znalaz%łeś0 %a1.") +S("CONGRATULATIONS!", "GRATULACJE!") +S("Collect treasure to access more different lands...", "Zbieraj skarby, by znaleźć nowe krainy...") +S("You feel that you have enough treasure to access new lands!", "Masz wystarczająco wiele skarbów, by znaleźć nowe krainy!") +S("Collect more treasures, there are still more lands waiting...", "Zbieraj skarby, nowe krainy czekają...") +S("You feel that the stars are right, and you can access R'Lyeh!", "Gwiazdy są na miejscu, R'Lyeh czeka!") +S("Kill monsters and collect treasures, and you may get access to Hell...", "Zabijaj potwory, zdobywaj skarby, może trafisz do Piekła...") +S("To access Hell, collect 10 treasures each of 9 kinds...", "By dostać się do Piekła, znajdź po 10 skarbów każdego z 9 rodzajów...") +S("Abandon all hope, the gates of Hell are opened!", "Porzuć wszelką nadzieję, bramy Piekła są otwarte!") +S("And the Orbs of Yendor await!", "I sfery Yendoru czekają!") +S("You switch places with %the1.", "Zamieniasz się miejscami z %abl1.") +S("You rejoin %the1.", "Połączy%łeś1 się z %abl1.") +S("The mirror shatters!", "Lustro pęka!") +S("The cloud turns into a bunch of images!", "Chmura zamienia się w obrazy!") +S("The slime reacts with %the1!", "Maź reaguje z %abl1!") +S("You drop %the1.", "Porzuci%łeś0 %a1.") +S("You feel great, like a true treasure hunter.", "Czujesz się świenie, jak prawdziwy łowca skarbów.") +S("Your eyes shine like gems.", "Twoje oczy błyszczą jak klejnoty.") +S("Your eyes shine as you glance at your precious treasures.", "Twoje oczy błyszczą, gdy patrzysz na swoje skarby.") +S("You glance at your great treasures.", "Patrzysz na swoje wspaniałe skarby.") +S("You glance at your precious treasures.", "Patrzysz na swoje drogocenne skarby.") +S("You glance at your precious treasure.", "Patrzysz na swój drogocenny skarb.") +S("Your inventory is empty.", "Nie masz żadnych skarbów.") +S("You teleport to a new location!", "Teleportujesz się do nowego miejsca!") +S("Could not open the score file: ", "Nie udało się otworzyć pliku: ") +S("Game statistics saved to %1", "Statystyki gry zapisane do %1") +S("Game loaded.", "Gra odczytana.") +S("You summon some Mimics!", "Przywoła%łeś0 Miraże!") +S("You summon a golem!", "Przywoła%łeś0 Golema!") +S("You will now start your games in %1", "Będziesz zaczynał grę %abl1") +S("Activated the Hyperstone Quest!", "Aktywowałeś Misję Hiperkamień!") +S("Orb power depleted!", "Zabrano sfery mocy!") +S("Orbs summoned!", "Sfery mocy przywołane!") +S("Orb power gained!", "Zdobyta moc!") +S("Dead orbs gained!", "Zdobyte Martwe Sfery!") +S("Orb of Yendor gained!", "Zdobyta Sfera Yendoru!") +S("Treasure gained!", "Skarb zdobyty!") +S("Lots of treasure gained!", "Mnóstwo skarbów zdobyte!") +S("You summon a sandworm!", "Przywoła%łeś0 Czerwia!") +S("You summon an Ivy!", "Przywoła%łeś0 Bluszcz!") +S("You summon a monster!", "Przywoła%łeś0 potwora!") +S("You summon some Thumpers!", "Przywoła%łeś0 dudniki!") +S("You summon a bonfire!", "Przywoła%łeś0 ognisko!") +S("Treasure lost!", "Skarb utracony!") +S("Kills gained!", "Zdobyto trupy!") +S("Activated Orb of Safety!", "Aktywowano Sferę Bezpieczeństwa!") +S("Teleported to %1!", "Przeniesiono w %abl1") + +S("Welcome to HyperRogue", "Witaj w HyperRogue") +S(" for Android", " na Android") +S(" for iOS", " na iOS") +S("! (version %1)\n\n", "! (wersja %1)\n\n") +S(" (press ESC for some hints about it).", " (naciśnij ESC by dostać wskazówki).") +S("Press 'c' for credits.", "Naciśnij 'c' by obejrzeć autorów") +S("game design, programming, texts and graphics by Zeno Rogue \n\n", + "projekt, programowanie, teksty i grafika: Zeno Rogue \n\n") +S("add credits for your translation here", "Teksty i tłumaczenie: Zeno Rogue\n\n") +S(" (touch to activate)", " (dotknij, by aktywować)") +S(" (expired)", " (wyczerpany)") +S(" [%1 turns]", " [kolejek: %1]") +S(", you", ", Ty") +S("0 = Klein model, 1 = Poincaré model", "0 = model Kleina, 1 = model Poincaré") +S("you are looking through it!", "patrzysz przez hiperboloidę!") +S("simply resize the window to change resolution", "po prostu zmień rozmiar okna") +S("[+] keep the window size, [-] use the screen resolution", "[+] zachowaj rozmiar okna, [-] użyj rozdzielczości ekranu") +S("+5 = center instantly, -5 = do not center the map", "+5 = centruj natychmiast, -5 = nie centruj") +S("press Space or Home to center on the PC", "naciśnij Space lub Home, by wycentrować na postaci") +S("You need special glasses to view the game in 3D", "Potrzebujesz specjalnych okularów, by oglądać grę w 3D") +S("You can choose one of the several modes", "Możesz wybrać jeden z kilku trybów") +S("ASCII", "ASCII") +S("black", "czarny") +S("plain", "prosty") +S("Escher", "Escher") +S("items only", "tylko przedmioty") +S("items and monsters", "przedmioty i potwory") +S("no axes", "bez osi") +S("auto", "auto") +S("light", "lekki") +S("heavy", "gruby") +S("The axes help with keyboard movement", "Osie pomagają, gdy gramy na klawiaturze") +S("Config file: %1", "Plik konfiguracyjny: %1") +S("joystick mode: automatic (release the joystick to move)", "tryb dżojstika: automatyczny (puść by ruszyć)") +S("joystick mode: manual (press a button to move)", "tryb dżojstika: ręczny (naciśnij przycisk)") +S("Reduce the framerate limit to conserve CPU energy", "Ogranicz fps, by oszczędzać energię") +S("Press F1 or right click for help", "Wciśnij F1 lub kliknij prawym, by uzyskać pomoc") +S("No info about this...", "Brak informacji o tym...") +S("Press Enter or F10 to save", "Wciśnij Enter lub F10, by zapisać i wyjść") +S("Press Enter or F10 to quit", "Wciśnij Enter lub F10, by wyjść z gry") +S("or 'r' or F5 to restart", "lub 'r' lub F5, by zacząć od początku") +S("or 't' to see the top scores", "lub 't' by zobaczyć najlepsze wyniki") +S("or another key to continue", "lub inny klawisz, by kontynuować") +S("It is a shame to cheat!", "Wstyd oszukiwać!") +S("Showoff mode", "Tryb pokazowy") +S("Quest status", "Stan misji") +S("GAME OVER", "KONIEC GRY") +S("Your score: %1", "Twój wynik: %1") +S("Enemies killed: %1", "Potwory pokonane: %1") +S("Orbs of Yendor found: %1", "Znalezione Sfery Yendoru: %1") +S("Collect 30 $$$ to access more worlds", "Znajdź 30 $$$ by iść do nowych krain") +S("Collect at least 10 treasures in each of 9 types to access Hell", "Znajdź po 10 skarbów w 9 typach, by się dostać do Piekła") +S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Znajdź 10 Czarciego Ziela, by znaleźć Sfery Yendoru") +S("Hyperstone Quest: collect at least 10 %1 in %the2", "Misja alternatywna: znajdź co najmniej 10 skarbów %abl2") +S("Hyperstone Quest completed!", "Misja alternatywna zakończona!") +S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Szukaj Sfer Yendoru w Piekle albo na Skrzyżowaniu!") +S("Unlock the Orb of Yendor!", "Otwórz Sferę Yendoru!") +S("Defeat 100 enemies to access the Graveyard", "Pokonaj 100 przeciwników, by trafić na Cmentarz") +S("(press ESC during the game to review your quest)", "(naciśnij ESC w trakcie gry, by zobaczyć stan swojej misji)") +S("you have cheated %1 times", "liczba oszustw: %1") +S("%1 turns (%2)", "kolejek: %1 (%2)") +S("last messages:", "ostatnie wiadomości: ") +S("time elapsed", "czas") +S("date", "data") +S("treasure collected", "zdobyte skarby") +S("total kills", "łączne zabicia") +S("turn count", "liczba kolejek") +S("cells generated", "wygenerowane pola") +S("t/left/right - change display, up/down - scroll, s - sort by", "t/lewo/prawo - zmiana, góra/dół - przewijanie, s - sortowanie") +S("kills", "zab") +S("time", "czas") +S("ver", "wer") +S("SORT", "SORT") +S("PLAY", "GRA") +S("Your total wealth", "Twoje łączne bogactwo") +S("treasure collected: %1", "zdobyte skarby: %1") +S("objects found: %1", "znalezione przedmioty: %1") +S("orb power: %1", "moc: %1") +S(" (click to drop)", " (naciśnij by porzucić)") +S("You can also scroll to the desired location and then press 't'.", "Możesz też przewinąć do miejsca docelowego i wcisnąć 't'.") +S("Thus, it is potentially useful for extremely long games, which would eat all the memory on your system otherwise.\n", + "Jest więc to użyteczne w bardzo długich grach, które inaczej by zjadły całą pamięć.") +S("You can touch the Dead Orb in your inventory to drop it.", "Dotknij Martwej Sfery na liście, by ją porzucić.") +S("This might be useful for Android devices with limited memory.", "To może się przydać, gdy Twoje urządzenie ma mało pamięci.") +S("You can press 'g' or click them in the list to drop a Dead Orb.", "Wciśnij 'g' lub kliknij Martwe Sfery na liście, by je porzucić.") +S("frames per second", "klatki na sekundę") +S("monsters killed: %1", "pokonane potwory: %1") +S("Drawing %1 (layer %2), F1 for help", "Rysujemy %1 (warstwa %2), F1 - pomoc") +S("hepta floor", "podłoga hepta") +S("hexa floor", "podłoga hex") +S("character", "postać") +S("ESC for menu/quest", "ESC - menu/misja") +S("vector graphics editor", "edytor grafiki wektorowej") +S("cheat mode", "tryb oszusta") +S("heptagonal game board", "plansza do gry z siedmiokątów") +S("triangular game board", "plansza do gry z trójkątów") +S("HyperRogue game board", "plansza do gry HyperRogue") +S("first page [Space]", "pierwsza strona [Space]") +S("exit configuration", "wyjdź z konfiguracji") +S("Configuration:", "Konfiguracja:") +S("video resolution", "rozdzielczość obrazu") +S("fullscreen mode", "tryb pełnoekranowy") +S("animation speed", "prędkość animacji") +S("dist from hyperboloid ctr", "odległość od centrum hiperboloidy") +S("scale factor", "współczynnik skali") +S("wall display mode", "tryb pokazywania ścian") +S("monster display mode", "tryb pokazywania potworów") +S("cross display mode", "tryb pokazywania osi") +S("background music volume", "głośność muzyki tła") +S("OFF", "WYŁ") +S("ON", "WŁ") +S("distance between eyes", "odległość między oczami") +S("framerate limit", "ograniczenie na fps") +S("joystick mode", "tryb dżojstika") +S("automatic", "automatyczny") +S("manual", "ręczny") +S("language", "język") +S("EN", "PL") +S("player character", "postać gracza") +S("male", "mężczyzna") +S("female", "kobieta") +S("use Shift to decrease and Ctrl to fine tune ", "użyj Shift by zmniejszyć, Ctrl by zwiększyć dokładność") +S("(e.g. Shift+Ctrl+Z)", " (na przykład Shift+Ctrl+Z)") +S("the second page [Space]", "druga strona [Space]") +S("special features [Space]", "opcje specjalne [Space]") +S("exit configuration", "wyjdź z konfiguracji") +S("see the help screen", "obejrzyj ekran pomocy") +S("save the current config", "zapisz obecną konfigurację") +S("(v) config", "(v) ust.") +S("Screenshot saved to %1", "Zrzut ekranu zapisany do %1") +S("You need an Orb of Teleport to teleport.", "Potrzebujesz Sfery Teleportacji, by to zrobić.") +S("Use arrow keys to choose the teleport location.", "Użyj strzałek, by wybrać cel teleportacji.") +S("openGL mode enabled", "włączono tryb OpenGL") +S("openGL mode disabled", "wyłączono tryb OpenGL") +S("openGL & antialiasing mode", "openGL i antialiasing") +S("anti-aliasing enabled", "włączono anti-aliasing") +S("anti-aliasing disabled", "wyłączono anti-aliasing") +S("You activate your demonic powers!", "Aktywowałeś moce demoniczne!") + +// Steam achievement messages + +S("New Achievement:", "Nowe osiągnięcie:") +S("Your total treasure has been recorded in the Steam Leaderboards.", "Twój wynik został zapisany w rankingach Steam.") +S("Congratulations!", "Gratulacje!") +S("You have improved your total high score and %1 specific high scores!", "Poprawi%łeś0 swój ogólny najlepszy wynik oraz %1 z wyników szczegółowych!") +S("You have improved your total and '%1' high score!", "Poprawi%łeś0 swój wynik ogólny, oraz swój wynik w kategorii '%P1!'") +S("You have improved your total high score on Steam. Congratulations!", "Poprawi%łeś0 swój ogólny najlepszy wynik na Steam. Gratulacje!") +S("You have improved %1 of your specific high scores!", "Poprawi%łeś0 %1 z wyników szczegółowych!") +S("You have improved your '%1' high score on Steam!", "Poprawi%łeś0 swój wynik w kategorii '%P1' na Steam!") +S("You have collected 10 treasures of each type.", "Znalaz%łeś0 10 skarbów każdego typu.") +S("This is your first victory!", "To Twoje pierwsze zwycięstwo!") +S("This has been recorded in the Steam Leaderboards.", "To zostało zapisane w Rankingach Steam.") +S("The faster you get here, the better you are!", "Im szybciej to osiągniesz, tym lepiej!") +S("You have improved both your real time and turn count. Congratulations!", "Poprawi%łeś0 swój najlepszy czas rzeczywisty i liczbę ruchów. Gratulacje!") +S("You have used less real time than ever before. Congratulations!", "Zajęło to mniej czasu rzeczywistego, niż wcześniej. Gratulacje!") +S("You have used less turns than ever before. Congratulations!", "Zajęło to mniej kolejek, niż kiedykolwiek wcześniej. Gratulacje!") + +// help texts. These are separated into multiple lines just for convenience, +// you don't have to follow. + +S( + "You have been trapped in a strange, non-Euclidean world. Collect as much treasure as possible " + "before being caught by monsters. The more treasure you collect, the more " + "monsters come to hunt you, as long as you are in the same land type. The " + "Orbs of Yendor are the ultimate treasure; get at least one of them to win the game!", + + "Trafi%łeś0 do dziwnej, nieeuklidesowej krainy. Zdobądź jak najwięcej skarbów, " + "zanim potwory Ciebie dopadną. Im więcej zdobędziesz skarbów, tym więcej potworów " + "w danej krainie na Ciebie poluje. Sfery Yendora są skarbem ostatecznym: zdobądź " + "Sferę Yendora, by wygrać grę!" + ) + +S( + "You can fight most monsters by moving into their location. " + "The monster could also kill you by moving into your location, but the game " + "automatically cancels all moves which result in that.\n\n", + + "Większość przeciwników zabijasz poprzez wejście na zajmowane przez nie pole. " + "Przeciwnik może Ciebie zabić w ten sam sposób, ale gra automatycznie zabrania " + "ruchów, które by do tego prowadziły.\n\n") + +S( + "Usually, you move by touching somewhere on the map; you can also touch one " + "of the four buttons on the map corners to change this (to scroll the map " + "or get information about map objects). You can also touch the " + "numbers displayed to get their meanings.\n", + "Zazwyczaj poruszasz się przez dotknięcie pola na mapie; możesz również " + "dotknąć jednego z przycisków w rogach, by to zmienić (by przewijać mapę albo " + "zdobyć informacje). Możesz też dotknąć liczb na ekranie, by poznać ich " + "znaczenie.\n") + +S("Move with mouse, num pad, qweadzxc, or hjklyubn. Wait by pressing 's' or '.'. Spin the world with arrows, PageUp/Down, and Home/Space. " + "To save the game you need an Orb of Safety. Press 'v' for config, ESC for the quest status and menu.\n\n", + "Ruszasz się myszą, klawiaturą numeryczną, qweadzxc, lub hjklyubn. Czekasz naciskając 's' lub '.'. " + "Obracasz świat strzałkami, PgUp/Dn, lub Home/Space. Naciśnij 'v' by zmienić ustawienia, ESC " + "by zobaczyć stan misji i menu.\n\n") + +S("See more on the website: ", "Więcej na stronie: ") + +S("special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n", + "Szczególne podziękowania dla poniższych osób za zgłoszone przez nich błędy, pomysły, porty i inną pomoc:\n\n%1\n\n") + +S( + "The total value of the treasure you have collected.\n\n" + "Every world type contains a specific type of treasure, worth 1 $$$; " + "your goal is to collect as much treasure as possible, but every treasure you find " + "causes more enemies to hunt you in its native land.\n\n" + "Orbs of Yendor are worth 50 $$$ each.\n\n", + + "Łączna wartość Twoich skarbów.\n\n" + "Każda kraina zawiera specyficzny dla niej skarb, wart 1 $$$; " + "Twoim celem jest zebranie jak najwięcej skarbów, ale każdy " + "znaleziony skarb powoduje, że w jego krainie więcej potworów na Ciebie poluje.\n\n" + "Sfery Yendoru są warte po 50 $$$.\n\n") + +S( + "The higher the number, the smoother the animations in the game. " + "If you find that animations are not smooth enough, you can try " + "to change the options ", + "Im większa liczba, tym płynniejsze są animacje. Jeśli animacja nie " + "jest dostatecznie płynna, spróbuj zmienić opcje") + +S("(Menu button) and select the ASCII mode, which runs much faster. " + "Depending on your device, turning the OpenGL mode on or off might " + "make it faster, slower, or cause glitches.", + "(Menu), tryb ASCII działa dużo szybciej. Tryb OpenGL również wpływa " + "na jakość grafiki." + ) + +S("(in the MENU). You can reduce the sight range, this should make " + "the animations smoother.", + "(w MENU). Możesz zmniejszyć zasięg widzenia, dzięki temu animacje " + "będą płynniejsze.") + +S("(press v) and change the wall/monster mode to ASCII, or change " + "the resolution.", + "(naciśnij 'v') i zmień tryb ścian/potworów na ASCII, albo zmień " + "rozdzielczość.") + +S( + "In this mode you can draw your own player character and floors. " + "Mostly for the development purposes, but you can have fun too.\n\n" + "f - floor, p - player (repeat 'p' for layers)\n\n" + "n - new shape, u - copy the 'player body' shape\n\n" + "1-9 - rotational symmetries, 0 - toggle axial symmetry\n\n" + "point with mouse and: a - add point, m - move nearest point, d - delete nearest point, c - nearest point again, b - add after nearest\n\n" + "s - save in C++ format (but cannot be loaded yet without editing source)\n\n" + "z - zoom, o - Poincaré model\n", + + "W tym trybie możesz narysować swoją własną postać albo podłogę. " + "Głównie w celu rozwijania gry, ale Ty też możesz się pobawić.\n\n" + "f - podłoga, p - gracz (powtarzaj, by zmienić warstwę)\n\n" + "n - nowy kształt, u - skopiuj standardową postać gracza\n\n" + "1-9 - symetrie obrotowe, 0 - symetria osiowa\n\n" + "wskaż myszą i: a - dodaj punkt, m - przesuń najbliższy punkt, d - skasuj najbliższy punkt, c - powtórz najbliższy punkt, b - po najbliższym\n\n" + "s - zapisz w formacie C++ (niestety obecnie nie można wczytać bez edytowania źródeł gry)\n\n" + "z - powiększenie, o - model Poincaré\n") + +S( + "These huge monsters normally live below the sand, but your movements have " + "disturbed them. They are too big to be slain with your " + "weapons, but you can defeat them by making them unable to move. " + "This also produces some Spice. They move two times slower than you.", + + "Te wielkie stworzenia normalnie żyją pod pustynnym piaskiem, ale Twoja obecność " + "na pustyni spowodowała ich wyjście na powierzchnię. Są za duże, byś m%ógł0 je " + "zaatakować swoją bronią, ale zginą, jeśli nie będą mogły się ruszyć -- to " + "produkuje także trochę Przyprawy. Czerwie ruszają się 2 razy wolniej od Ciebie.") + +S("The tentacles of Cthulhu are like sandworms, but longer. " + "They also withdraw one cell at a time, instead of exploding instantly.", + + "Macki Cthulhu są podobne do Pustynnych Czerwi, ale dłuższe. " + "W przeciwieństwie do nich, nie eksplodują po zablokowaniu, tylko cofają się " + "pod ziemię, po 1 polu na kolejkę.") + +S( + "A huge plant growing in the Jungle. Each Ivy has many branches, " + "and one branch grows per each of your moves. Branches grow in a clockwise " + "order. The root itself is vulnerable.", + "Wielka roślina z dżungli. Bluszcz zazwyczaj ma wiele gałęzi, po każdym Twoim " + "ruchu jedna z nich rośnie. Gałęzie rosną w kolejnosci zegarowej. Sam korzeń " + "nie atakuje, zatem goły korzeń łatwo ściąć.\n") + +S("The Alchemists produce magical potions from pools of blue and red slime. You " + "can go through these pools, but you cannot move from a blue pool to a red " + "pool, or vice versa. Pools containing items count as colorless, and " + "they change color to the PC's previous color when the item is picked up. " + "Slime beasts also have to keep to their own color, " + "but when they are killed, they explode, destroying items and changing " + "the color of the slime and slime beasts around them.", + "Alchemicy produkują magiczne napoje z niebieskiej i czerwonej mazi. Możesz " + "poruszać się poprzez maź, ale nie możesz przesunąć się z pola niebieskiego " + "na czerwone, ani z powrotem. Pola zawierające przedmioty są bezbarwne, " + "jak zabierzemy przedmiot, to zmieniają kolor na kolor pola, na którym " + "gracz był wcześniej. Maziste Stwory również ograniczone są do swojego koloru. " + "Gdy je zabijesz, eksplodują, niszcząc przedmioty i zmieniając kolor mazi wokół nich.\n") + +S( + "These creatures are slow, but very powerful... more powerful than you. " + "You need some more experience in demon fighting before you will be able to defeat them. " + "Even then, you will be able to slay this one, but more powerful demons will come...\n\n" + "Each 10 lesser demons you kill, you become powerful enough to kill all the greater " + "demons on the screen, effectively turning them into lesser demons.", + + "Te demony są powolne, ale bardzo silne... silniejsze od Ciebie. " + "Potrzebujesz zdobyć trochę doświadczenia, zanim będziesz w stanie je pokonać. " + "Nawet wtedy, przyjdą jeszcze silniejsze demony...\n\n" + "Za każdym razem, gdy pokonasz 10 mniejszych demonów, stajesz się dostatecznie silny, " + "by pokonać wszystkie Wielkie Demony na ekranie. Stają się one w tym momencie " + "Mniejszymi Demonami.") + +S("These creatures are slow, but they often appear in large numbers.", + "Te demony są powolne, ale często pojawiają się w dużych ilościach.") + +S("A big monster from the Living Caves. A dead Troll will be reunited " + "with the rocks, causing some walls to grow around its body.", + "Duży stwór z Żyjących Jaskiń. Martwy Troll połączy się ze skałą, " + "powodując rozrost skał wokół jego ciała.") + +S("Huge, impassable walls which separate various lands.", + "Wielkie ściany, które oddzielają od siebie poszczególne krainy.") + +S( + "This cave contains walls which are somehow living. After each turn, each cell " + "counts the number of living wall and living floor cells around it, and if it is " + "currently of a different type than the majority of cells around it, it switches. " + "Items count as three floor cells, and dead Trolls count as five wall cells. " + "Some foreign monsters also count as floor or wall cells.\n", + "Ściany tej jaskini sa żywe. W każdej kolejce, każde pole liczy, ile wokół niego " + "jest pól ściany i pól ziemi, i jeśli jest innego typu niż większość pól wokół " + "niego, to zmienia typ na przeciwny. Przedmioty liczą się jako 3 pola ziemi, " + "martwe Trolle jako 5 pól ściany. Niektóre potwory z innych krain również liczą się " + "jako ziemia lub ściana.\n") + +S( + "This forest is quite dry. Beware the bushfires!\n" + "Trees catch fire on the next turn. The temperature of the grass cells " + "rises once per turn for each fire nearby, and becomes fire itself " + "when its temperature has risen 10 times.\n" + "You can also cut down the trees. Big trees take two turns to cut down.", + "Ta puszcza jest wyschnięta. Uważaj na pożary!\n" + "Sąsiednie drzewa zajmują się ogniem w następnej kolejce. Temperatura " + "pola bez drzewa rośnie o 1 na kolejkę z każdym ogniem w sąsiedztwie, i gdy " + "wzrośnie do 10, to pole również staje się ogniem.\n" + "Możesz też ścinać drzewa. Ścięcie dużego drzewa zajmuje dwie kolejki." + ) + +S("A big and quite intelligent monster living in the Icy Land.", + "Duża i całkiem inteligentna bestia z Krainy Lodu.") + +S( + "A nasty predator from the Icy Land. Contrary to other monsters, " + "it tracks its prey by their heat.", + "Niebezpieczny drapieżnik z Krainy Lodu. W przeciwieństwie do innych " + "stworów, śledzi ofiarę po jej cieple.") + +S("Rangers take care of the magic mirrors in the Land of Mirrors. " + "They know that rogues like to break these mirrors... so " + "they will attack you!", + "Strażnicy chronią luster w Krainie Luster. Wiedzą, że złodzieje lubią " + "rozbijać lustra... także spodziewaj się ataku!") + +S("A nasty creature native to the Living Caves. They don't like you " + "for some reason.", + "Brzydki stwór z Żywych Jaskiń. Jakoś Ciebie nie lubi.") + +S("A tribe of men native to the Desert. They have even tamed the huge Sandworms, who won't attack them.", + "Plemię ludzi żyjących na Pustyni. Oswoili oni Pustynne Czerwie, dzięki czemu żyją razem pokojowo.") + +S("This giant ape thinks that you are an enemy.", "Ta małpa uważa, że jesteś jej przeciwnikiem.") + +S("A magical being which copies your movements.", "Magiczna istota kopiująca Twoje ruchy.") + +S("A magical being which copies your movements. " + "You feel that it would be much more useful in an Euclidean space.", + "Magiczna istota kopiująca Twoje ruchy. W przestrzeni euklidesowej byłaby dużo bardziej przydatna.") + +S("You can summon these friendly constructs with a magical process.", + "Przyjazna konstrukcja, tworzona poprzez magiczny proces.") + +S("A majestic bird, who is able to fly very fast.", + "Ten majestatyczny ptak bardzo szybko lata.") + +S("A monster who is able to live inside the living cave wall.", + "Sączaki żyją w ściane Żywej Jaskini.") + +S("A typical Graveyard monster.", "Typowy cmentarny stwór.") + +S("A typical monster from the Graveyard, who moves through walls.\n\n" + "There are also wandering Ghosts. They will appear " + "if you do not explore any new places for a long time (about 100 turns). " + "They can appear anywhere in the game.", + "Typowy cmentarny stwór. Może przechodzić przez ściany.\n\n" + "Są też błądzące Duchy, które pojawiają się, gdy nie zwiedzasz " + "nowych miejsc przez długi czas (około 100 kolejek). Duchy te " + "mogą pojawić się w dowolnym miejscu w grze." + ) + +S("Necromancers can raise ghosts and zombies from fresh graves.", + "Nekromanci wzbudzają duchy i zombie ze świeżych grobów.") + +S("A creepy monster who follows you everywhere in the Graveyard.", + "Ten odrażający potwór chodzi za Tobą po cmentarzu!") + +S("People worshipping Cthulhu. They are very dangerous.", + "Wyznawcy Cthulhu, bardzo niebiezpieczni.") + +S("People worshipping Cthulhu. This one is especially dangerous, " + "as he is armed with a weapon which launches fire from afar.", + "Wyznawcy cthulhu. Ten jest szczególnie niebezpieczny, bo " + "może z odległości rozpalić ogień w Twojej okolicy.") + +S("This dangerous predator has killed many people, and has been sent to Cocytus.", + "Ten niebezpieczny drapieżnik zabił wielu ludzi, i został zesłany do Kocytu.") + +S("This white dog is able to run all the time. It is the only creature " + "able to survive and breed in the Land of Eternal Motion.", + "Ten biały piesek jest w stanie biegać przez całe swoje życie. Jest to jedyne " + "stworzenie, które jest w stanie przeżyć w Krainie Wiecznego Ruchu.") + +S("Demons of Hell do not drown when they fall into the lake in Cocytus. " + "They turn into demonic sharks, enveloped in a cloud of steam.", + "Demony nie topią się, gdy wpadną w jezioro Kocyt. Zamieniają się " + "w demoniczne rekiny, otoczone chmurą pary.") + +S("These fairies would rather burn the forest, than let you get some Fern Flowers. " + "The forest is infinite, after all...\n\n" + "Fire Fairies transform into fires when they die.", + "Rusałki wolą spalić las, niż pozwolić Ci zdobyć Kwiaty Paproci. W końcu " + "las jest nieskończony...\n\n" + "Rusałki zamieniają się w ogień, gdy giną.") + +S("These warriors of the Forest wield exotic weapons called hedgehog blades. " + "These blades protect them from a frontal attack, but they still can be 'stabbed' " + "easily by moving from one place next to them to another.", + "Ci wojownicy z Puszczy walczą egzotyczną bronią, Jeżowym Ostrzem. " + "Ostrza te bronią je przed atakiem z frontu, ale za to możesz ich łatwo 'dźgnąć' " + "poprzez przejście z jednego pola sąsiadującego z nimi na inne.") + +S("This being radiates an aura of wisdom. " + "It is made of a beautiful crystal, you would love to take it home. " + "But how is it going to defend itself? Better not to think of it, " + "thinking causes your brain to go hot...\n\n" + "Crystal Sages melt at -30 °C, and they can rise the temperature around you from afar.", + "Ta istota promieniuje mądrością. Jest zrobiona z pięknego kryształu, na pewno " + "bardzo cennego. Ciekawe, jak zamierza się przed Tobą bronić? Lepiej o tym nie myśleć, " + "myślenie za bardzo Ciebie rozgrzewa...\n\n" + "Kryształowi Mędrcy topią się w -30 °C, i powodują wzrost temperatury wokół Ciebie.") + +S("Cold white gems, found in the Icy Land.", "Zimne białe kamienie z Krainy Lodu.") + +S("An expensive metal from the Living Caves. For some reason " + "gold prevents the living walls from growing close to it.", + "Drogocenny metal z Żyjących Jaskiń. Złoto utrudnia wzrost ścian wokół niego.") + +S("A rare and expensive substance found in the Desert. " + "It is believed to extend life and raise special psychic powers.", + "Rzadka i droga substancja z Pustyni. Podobno wydłuża życie i daje moce psychiczne.") + +S("A beautiful gem from the Jungle.", "Piękny klejnot z Dżungli.") + +S( + "A wonderful beverage, apparently obtained by mixing red and blue slime. You definitely feel more " + "healthy after drinking it, but you still fell that one hit of a monster is enough to kill you.", + "Cudowny napój, powstały z mieszania czerwonej i niebieskiej mazi. Po jej wypiciu czujesz " + "się zdecydowanie lepiej, ale wciąż jedno uderzenie potwora może Ciebie powalić.") + +S("A piece of a magic mirror, or a mirage cloud, that can be used for magical purposes. Only mirrors and clouds " + "in the Land of Mirrors leave these.", + "Odłamek szkła z magicznego lustra, albo fragment mirażowej chmury. Może zostać użyty do magii. " + "Tylko lustra i chmury z Krainy Luster zostawiają odłamki.") + +S("These sinister totems contain valuable gems.", + "Ten złowieszczy totem zawiera cenne klejnoty.") + +S("These star-shaped flowers native to Hell are a valuable alchemical component.", + "Ta piekielna roślina w kształcie gwiazdy jest cennym składnikiem alchemicznym.") + +S("This statue is made of materials which cannot be found in your world.", + "Ta statua jest zrobiona z materiałów, których nie ma w Twoim świecie.") + +S("One of few things that does not cause the floor in the Land of Eternal Motion to collapse. Obviously they are quite valuable.", + "Pióro Feniksa jest tak lekie, że podłoga z Krainy Wiecznego Ruchu pod nim nie spada. " + "Takie pióra muszą być bardzo cenne.") + +S("Cold blue gems, found in the Cocytus.", "Zimne niebieskie kamienie, znajdowane na zamarźniętym Kocycie.") + +S("These bright yellow gems can be found only by those who have mastered the Crossroads.", + "Te jasne, żółte klejnoty mogą znaleźć tylko mistrze Skrzyżowań.") + +S("That's all you need to unlock the Orb of Yendor! Well... as long as you are able to return to the Orb that this key unlocks...\n\n" + "Each key unlocks only the Orb of Yendor which led you to it.", + "To jest to, czego potrzebujesz, by otworzyć Sferę Yendoru! O ile umiesz do niej trafić...\n" + "Każdy klucz otwiera tylko jedną Sferę, która Ciebie do niego doprowadziła.") + +S("These orbs can be found in the Graveyard. You think that they were once powerful magical orbs, but by now, their " + "power is long gone. No way to use them, you could as well simply drop them...\n\n", + "Na cmentarzu jest mnóstwo tych sfer. Chyba były to kiedyś potężne magiczne kule, ale ich " + "moc dawno przeminęła. Nie ma jak ich użyć, także może lepiej je po prostu zostawić...\n\n") + +S( + "This wonderful Orb can only be collected by those who have truly mastered this hyperbolic universe, " + "as you need the right key to unlock it. Luckily, your psychic abilities will let you know " + "where the key is after you touch the Orb.", + "Ta cudowna sfera może być zdobyta tylko przez prawdziwych mistrzów tego świata. " + "By ją otworzyć, potrzebujesz klucza. Na szczęście Twoje moce psychiczne powiedzą Ci, " + "gdzie jest klucz, gdy dotkniesz Sfery.") + +S( + "This orb can be used to invoke the lightning spell, which causes lightning bolts to shoot from you in all directions.", + "Ta sfera pozwala rzucić czar Błyskawica, który powoduje wystrzelenie błyskawicy w każdym kierunku.") + +S("This orb can be used to invoke a flash spell, which destroys almost everything in radius of 2.", + "Ta sfera pozwala rzucić czar Błysk, który niszczy wszystko w promieniu 2.") + +S("This orb can be used to invoke a wall of ice. It also protects you from fires.", + "Ta sfera zostawia za Tobą ścianę lodu, a także chroni Ciebie przed ogniem.") + +S("This orb can be used to move faster for some time.", + "Ta sfera powoduje, że przez pewien czas poruszasz się szybciej.") + +S("This orb can be used to summon friendly golems. It is used instantly when you pick it up.", + "Ta sfera przywołuje przyjazne golemy. Jest natychmiast używana w momencie podniesienia.") + +S("This orb can protect you from damage.", "Ta sfera chroni Ciebie przed obrażeniami od potworów.") + +S("This orb lets you instantly move to another location on the map. Just click a location which " + "is not next to you to teleport there. ", + "Ta sfera pozwala Ci natychmiast przenieść się do innego miejsca na mapie. Wystarczy " + "kliknąć pole, które nie jest obok Ciebie.") + +S("This orb lets you instantly move to a safe faraway location. Knowing the nature of this strange world, you doubt " + "that you will ever find the way back...\n\n" + "Your game will be saved if you quit the game while the Orb of Safety is still powered.\n\n" + "Technical note: as it is virtually impossible to return, this Orb recycles memory used for the world so far (even if you do not use it to save the game). ", + "Ta sfera pozwala Ci natychmiast przenieść się do bezpiecznego miejsca. Znając naturę tego " + "świata, zapewne nigdy nie trafisz z powrotem...\n\n" + "Jeśli wyjdziesz z gry podczas gdy Sfera Bezpieczeństwa wciąż ma moc, gra zostanie zapisana.\n\n" + "Uwaga techniczna: nawet jeśli nie zapiszesz gry, ta sfera czyści całą pamięć o świecie gry. ") + +S("This orb allows attacking Hedgehog Warriors directly, as well as stabbing other monsters.\n", + "Ta sfera pozwala bezpośrednio atakować Wojowników-Jeże, a także dźgać pozostałych przeciwników.\n") + +S("This flower brings fortune to the person who finds it.\n", + "Ta roślina daje szczęście temu, kto je znajdzie.\n") + +S("Ice Walls melt after some time has passed.", "Lodowe ściany topią się po pewnym czasie.") + +S("A natural terrain feature of the Desert.", "Naturalny teren z Pustyni.") + +S("You can go inside the Magic Mirror, and produce some mirror images to help you.", + "Możesz wejść w Magiczne Lustro, by Twoje odbicia z niego wyszły i Ci pomogły.") + +S( + "Tiny droplets of magical water. You see images of yourself inside them. " + "Go inside the cloud, to make these images help you.", + "Malutkie kropelki magicznej wody, w których widać Twój obraz. Wejdź do środka chmury, " + "by te obrazy Ci pomogły.") + +S("A device that attracts sandworms and other enemies. You need to activate it.", + "To urządzenie przyciąga czerwie i innych przeciwników. Musisz je aktywować.") + +S("A heap of wood that can be used to start a fire. Everything is already here, you just need to touch it to fire it.", + "Stos drewna. Wszystko gotowe, wystarczy podpalić.") + +S("An ancient grave.", "Stary grób.") + +S("A fresh grave. Necromancers like those.", "Świeży grób. Nekromanci to lubią.") + +S("A piece of architecture typical to R'Lyeh.", "Architektura typowa dla R'Lyeh.") + +S("An impassable lake in Cocytus.", "Nie możesz przejść przez Jezioro Kocyt.") + +S("You can walk on it... but beware.", "Możesz tu przejść, ale uważaj!") + +S("It was a floor... until something walked on it.", "Tu kiedyś była podłoga, ale coś po niej przeszło.") + +S( + "This land is a quick gateway to other lands. It is very easy to find other lands " + "from the Crossroads. Which means that you find monsters from most other lands here!\n\n" + "As long as you have found enough treasure in their native lands, you can " + "find magical items in the Crossroads. Mirror Land brings mirrors and clouds, " + "and other land types bring magical orbs.\n\n" + "A special treasure, Hyperstone, can be found on the Crossroads, but only " + "after you have found 10 of every other treasure.", + "Ta kraina jest szybkim przejściem do pozostałych krain. Bardzo łatwo dostać się " + "stąd do pozostałych krain. Również potwory z tych krain łatwo tutaj wejdą!\n\n" + "Możesz znaleźć magiczne przedmioty na Skrzyżowaniu, jeśli zdoby%łeś0 wystarczająco " + "wiele skarbów w ich rodzinnych krainach. Są to sfery, magiczne lustra i chmury.\n\n" + "Specyficzne skarby Skrzyżowań, Hiperkamienie, można znaleźć na Skrzyżowaniu, ale tylko " + "po znalezieniu 10 jednostek każdego innego skarbu.") + +S("A hot land, full of sand dunes, mysterious Spice, and huge and dangerous sand worms.", + "Gorąca ziemia, pełna wydm, tajemniczej Przyprawy, i wielkich Pustynnych Czerwi.") + +S( + "A very cold land, full of ice walls. Your mere presence will cause these ice walls to " + "melt, even if you don't want it.", + "Bardzo zimna kraina, pełna lodowych ścian. Wystarczy Twoja obecność, by te ściany " + "się roztopiły. Nawet, jak tego nie chcesz.") + +S("A land filled with huge ivy plants and dangerous animals.", + "Kraina pełna wielkiego pnącego bluszczu i niebezpiecznych bestii.") + +S("A strange land which contains mirrors and mirages, protected by Mirror Rangers.", + "Dziwna kraina, gdzie można znaleźć magiczne lustra i chmury, bronione przez " + "Strażników Luster.") + +S("All the monsters you kill are carried to this strange land, and buried. " + "Careless Rogues are also carried here...", + "Pochowane są tu wszystkie potwory, które zabijasz. A także poszukiwacze skarbów, którzy " + "nie uważali...") + +S("An ancient sunken city which can be reached only when the stars are right.\n\n" + "You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Prastare zatopione miasto, do którego można dostać się tylko, gdy gwiazdy są " + "na swoich miejscach.\n\n" + "Po znalezieniu 5 Statuetek Cthulhu możesz w R'Lyeh trafić na Świątynie Cthulhu.") + +S("A land filled with demons and molten sulphur. Abandon all hope ye who enter here!", + "Kraina pełna demonów i stopionej siarki. Ty, który wchodzisz, żegnaj się z nadzieją!") + +S("This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.", + "Zamarznięte jezioro. Piekielna wersja Krainy Lodu, w której ciepło Twojego ciała topi ziemię pod Tobą, a nie " + "ściany.") + +S("A land where you cannot stop, because every piece of floor is extremely unstable. Only monsters who " + "can run forever are able to survive there, and only phoenix feathers are so light that they do not disturb " + "the floor.\n", + "Kraina, w której nie możesz przestać się ruszać, bo każdy fragment podłogi jest bardzo niestabilna. " + "Jedynie stworzenia będące w stanie wiecznie się ruszać mogą tu przeżyć, i jedynie pióra feniksa " + "są na tyle lekkie, by nie zaburzyć podłogi.") + +S("Affects looks and grammar", "Wpływa na wygląd i gramatykę") + +S("first joystick: movement threshold", "dżojstik 1: próg ruchu") +S("first joystick: execute movement threshold", "dżojstik 1: próg wykonania ruchu") +S("second joystick: pan threshold", "dżojstik 2: próg przewijania") +S("second joystick: panning speed", "dżojstik 2: prędkość przewijania") +S("%The1 is frozen!", "%1 zamarzł%oa1!") +S("%The1 burns!", "%1 się spalił%oa1!") +S("message flash time", "czas pokazywania wiadomości") + +S("skin color", "kolor skóry") +S("weapon color", "kolor broni") +S("hair color", "kolor włosów") +S("dress color", "kolor sukienki") +S("Shift=random, Ctrl=mix", "Shift=losowo, Ctrl=miks") + +S("Euclidean mode", "tryb euklidesowy") +S("Return to the hyperbolic world", "powrót na hiperboloidę") +S("Choose from the lands visited this game.", "Wybierz spośród odwiedzonych krain.") +S("Scores and achievements are not", "Wyniki i osiągnięcia nie są"); +S("saved in the Euclidean mode!", "zapamiętywane w tym trybie!"); + +// Android buttons (some are not translated because there are no good short words in Polish) +S("MOVE", "RUCH") +S("BACK", "OK") +S("DRAG", "DRAG") +S("INFO", "INFO") +S("MENU", "MENU") +S("QUEST", "MISJA") +S("HELP", "POMOC") +S("NEW", "NOWA") +S("PLAY", "GRAJ") +S("SHARE", "SHARE") +S("HyperRogue for Android", "HyperRogue dla Android") +S("Date: %1 time: %2 s ", "Data: %1 czas: %2 s ") +S("distance: %1\n", "odległość: %1\n") +S("Cheats: ", "Oszustwa: ") +S("Score: ", "Wynik: ") +S("Kills: ", "Zabicia: ") +S("Retrieving scores from Google Leaderboards...", "Ściągam wyniki z rankingów Google...") +S("Scores retrieved.", "Wyniki ściągnięte.") + +S("Your total treasure has been recorded in the Google Leaderboards.", "Twój wynik został zapisany w rankingach Google.") +S("You have improved your total high score on Google. Congratulations!", "Poprawi%łeś0 swój ogólny najlepszy wynik na Google. Gratulacje!") +S("You have improved your '%1' high score on Google!", "Poprawi%łeś0 swój wynik w kategorii '%P1' na Google!") +S("This has been recorded in the Google Leaderboards.", "To zostało zapisane w Rankingach Google.") + +// this text changed a bit: + +S("Ever wondered how some boardgame would look on the hyperbolic plane? " + "I wondered about Go, so I have created this feature. Now you can try yourself!\n" + "Enter = pick up an item (and score), space = clear an item\n" + "Other keys place orbs and terrain features of various kinds\n" + "In the periodic editor, press 0-4 to switch walls in different ways\n", + "Zastanawia%łeś0 się może, jak jakaś gra planszowa wyglądałaby na płaszczyźnie " + "hiperbolicznej? Ja się zastanawiałem nad Go, i postanowiłem to sprawdzić. Teraz " + "Ty też możesz sprawdzić!\n" + "Enter = podnieś przedmiot, space = zabierz przedmiot\n" + "Pozostałe klawisze kładą różnego rodzaju przedmioty\n" + "W edytorze okresowym, klawisze 0-4 zmieniają ściany na różne sposoby") + +S("Periodic Editor", "Edytor okresowy") +// also translate this line: +// "In the periodic editor, press 0-4 to switch walls in different ways\n", + +S("Collect 60 $$$ to access even more lands", "Znajdź 60 $$$ by iść do kolejnych krain") + +// Emerald Mine + +N("Emerald Mine", GEN_F, "Kopalnia Szmaragdów", "Kopalnie Szmaragdów", "Kopalnię Szmaragdów", "w Kopalni Szmaragdów") +N("Pikeman", GEN_M, "Pikinier", "Pikinierzy", "Pikiniera", "Pikinierem") +N("Flail Guard", GEN_M, "Strażnik z cepem", "Strażnicy z cepami", "Strażnika z cepem", "Strażnikiem z cepem") +N("Miner", GEN_M, "Górnik", "Górnicy", "Górnika", "Górnikiem") +N("Emerald", GEN_O, "Szmaragd", "Szmaragdy", "Szmaragd", "Szmaragdem") + +Orb("the Mind", "Psychiki") + +S( + "Evil people are mining for emeralds in this living cave. " + "It does not grow naturally, but it is dug out in a regular " + "pattern, which is optimal according to the evil engineers.", + "Źli ludzie szukają szmaragdów w tej żywej jaskini. " + "Nie rośnie ona naturalnie -- ludzie wykopują regularne " + "wzory, które, zgodnie z oceną złych inżynierów, są 'optymalne'. ") + +S( + "Miners have special tools for dealing with the Living Cave. " + "When they die, these tools activate, destroying the living cave " + "around them.", + "Górnicy mają specjalne narzędzia do kopania w Żywych Jaskiniach. " + "Kiedy giną, te narzędzia się uruchamiają, powodując, że żywa " + "jaskinia wokół nich obumiera.") + +S( + "When Pikemen move, they attack all cells which are now adjacent to them. " + "Luckily, they can be killed in the same way.\n\n" + "They never move if this would attack their friends.", + "Kiedy Pikinier się rusza, atakuje wszystkie komórki, z którymi sąsiaduje " + "po wykonaniu ruchu. Na szczęście, jego samego można pokonać taką samą " + "metodą.\n\n" + "Pikinier się nie rusza, jeśli by w ten sposób zaatakował przyjaciela.") + +S( + "This guard of the Emerald Mine is wielding a huge flail. " + "You cannot attack him directly, as the flail would still hit you then. " + "Luckily, you have learned a trick: if you step away from him, " + "he will hit himself with the flail!", + + "Ten strażnik Kopalni Szmaragdów jest uzbrojony w wielki cep bojowy. " + "Nie możesz go zaatakować bezpośrednio, bo cep by Ciebie uderzył. " + "Na szczęście, znasz sztuczkę: jak się od niego odsuniesz, " + "strażnik uderzy cepem samego siebie!") + +S("A precious green gem from the Emerald Mines.", "Cenny klejnot z Kopalni Szmaragdów.") + +S("%The1 pierces %the2!", "%1 przebi%ł1 %a2!") + +S("Make him hit himself by walking away from him.", + "Odejdź od niego, by sam się zaatakował.") + +S("This orb allows you to instantly kill a non-adjacent enemy by clicking it. " + "Each use drains 30 charges.", + "Ta sfera pozwala natychmiastowo zabić niesąsiadującego przeciwnika (klikając go). " + "Każde użycie zmniejsza poziom naładowania o 30.") + +S("%The1 is immune to mental blasts!", "%1 jest odporn%y1 na atak psychiczny!") +S("You kill %the1 with a mental blast!", "Zabi%łeś1 %a2 mocą psychiczną!") + +// Vineyard + +N("Vineyard", GEN_F, "Winnica", "Winnice", "Winnicę", "w Winnicy") +N("Vine Beast", GEN_M, "Winny Stwór", "Winne Stwory", "Winnego Stwora", "Winnym Stworem") +N("Vine Spirit", GEN_M, "Winny Duszek", "Winne Duszki", "Winnego Duszka", "Winnym Duszkiem") +N("vine", GEN_F, "winorośl", "winorośle", "winorośl", "winoroślą") +N("partial fire", GEN_M, "częściowy ogień", "częściowe ognie", "częściowy ogień", "częściowym ogniem") +N("Wine", GEN_N, "Wino", "Wina", "Wino", "Winem") + +S( "This cell is partially on fire.", "To pole częściowo się pali.") + +S( + "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n" + "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.", + "Winnica jest wypełniona winoroślami. Bardzo gęsta siatka linii prostych...\n\n" + "Winne Bestie i Duszki zmieniają winorośle w trawę i z powrotem.") + +S("A vine is growing here... but only on a half of the cell. How is that even possible?!" + "Most monsters cannot move from this cell to the cell containing the other half. " + "Vine spirits can move only to the adjacent cells which are also adjacent to the " + "other half.", + "Tu rośnie winorośl... ale tylko na połowie pola. Jak to w ogóle jest możliwe?!" + "Większość stworzeń nie może ruszyć się z tego pola na pole zawierające drugą połowę " + "winorośli. Winne duszki mogą się ruszyć tylko na te sąsiednie pola, które sąsiadują " + "także z drugą połową.") + +S( + "A beast made of vines!\n\n" + "Vine Beasts turn into vines when they die.", + "Stworzenie zrobione z winorośli!\n\n" + "Winne Stwory zmieniają się w winorośle, gdy giną.") + +S( "A spirit living in the vines!\n\n" + "Vine Spirits destroy the vines when they die.", + "Duch żyjący w winoroślach!\n\n" + "Winne Duszki niszczą winorośle, gdy giną.") + +S("Wine grown under hyperbolic sun would be extremely prized in your home location.", + "Wino uprawiane pod hiperbolicznym słońcem, byłoby bardzo cenne w Twojej " + "krainie.") + +S("This orb allows one to pass through all kinds of walls and chasms.", + "Ta sfera pozwala przechodzić przez wszelkie ściany i przepaście.") + +S("You cannot attack through the Vine!", + "Nie możesz atakować poprzez winorośl!") + +Orb("Aether", "Eteru") + +// Dead Caves + +N("Dead Cave", GEN_F, "Martwa Jaskinia", "Martwe Jaskinie", "Martwą Jaskinię", "w Martwej Jaskini") +N("Dark Troll", GEN_M, "Mroczny Troll", "Mroczne Trolle", "Mrocznego Trolla", "Mrocznym Trollem") +N("Earth Elemental", GEN_M, "Żywiołak", "Żywiołaki", "Żywiołaka", "Żywiołakiem") +N("dead wall", GEN_F, "martwa ściana", "martwe ściany", "martwą ścianę", "martwą ścianą") +N("dead floor", GEN_F, "martwa ziemia", "martwe ziemie", "martwą ziemię", "martwą ziemią") +N("rubble", GEN_O, "gruz", "gruzy", "gruz", "gruzem") +N("Silver", GEN_N, "Srebro", "Srebra", "Srebro", "Srebrem") + +S("A precious metal from the Dead Caves.", "Drogocenny metal z Martwej Jaskini.") + +S( "A Troll without the power of Life.", "Troll bez mocy Życia.") + +S( + "A rare unliving construct from the Dead Caves. " + "It instantly destroys cave walls next to its path, and also leaves " + "an impassable wall behind it. You suppose that this impassable wall helps it to " + "escape from some threats. You hope you won't meet these threats...", + + "Rzadka konstrukcja z Martwych Jaskiń. " + "Natychmiast niszczy skalne ściany przy jego trasie, i tworzy " + "za sobą ścianę skały. Przypuszczasz, że ta ściana pomaga mu " + "uciekać przed jakimiś zagrożeniami. Masz nadzieję, że nie spotkasz tych " + "zagrożeń...") + +S("%The1 punches %the2!", "%1 uderzy%ł1 %a2!") +S("%The1 is destroyed by the forces of Life!", "Siły Życia zniszczyły %a1!") +S( "Somehow, this cave has not received the spark of Life yet.", + "Dziwnym trafem, ta jaskinia jeszcze nie zdobyła iskry Życia.") + +// Hive +N("Hive", GEN_N, "Mrowisko", "Mrowiska", "Mrowisko", "w Mrowisku") +N("Red Hyperbug", GEN_M, "Czerwony Hiperinsekt", "Czerwone Hiperinsekty", "Czerwonego Hiperinsekta", "Czerwonym Hiperinsektem") +N("Green Hyperbug", GEN_M, "Zielony Hiperinsekt", "Zielone Hiperinsekty", "Zielonego Hiperinsekta", "Zielonym Hiperinsektem") +N("Blue Hyperbug", GEN_M, "Niebieski Hiperinsekt", "Niebieskie Hiperinsekty", "Niebieskiego Hiperinsekta", "Niebieskim Hiperinsektem") +N("Royal Jelly", GEN_N, "Królewskie Mleczko", "Królewskie Mleczka", "Królewskie Mleczko", "Królewskim Mleczkiem") +N("weird rock", GEN_N, "dziwna skała", "dziwne skały", "dziwną skałę", "dziwną skałą") + +Orb("Invisibility", "Niewidzialności") + +S("A weirdly colored rock. Hyperentomologists claim that the " + "Hyperbug armies use these rocks to navigate back home after a victorious battle.", + "Ta skała ma dziwny kolor. Hiperentomolodzy twierdzą, że roje Hiperinsektów " + "używają tych skał do nawigacji, by wrócić do domu po wygranej bitwie.") + +S("%The1 fights with %the2!", "%1 zaatakował %a2!") + +S("The Hive is filled with Hyperbugs. They are huge insects which look a bit like " + "ants, a bit like bees, and a bit like roaches. " + "They live in circular nests, and an army of Hyperbugs will attack any intruder, " + "including you and enemy Hyperbugs. Will you manage to get to the " + "heart of such a nest, and get the precious Royal Jelly?", + "Mrowisko jest wypełnione Hiperinsektami. Te wielkie owady wyglądają trochę jak " + "mrówki, trochę jak pszczoły, trochę jak karaluchy. Żyją w okrągłych gniazdach, " + "i atakują każdego najeźdźcę, łącznie z Tobą i wrogimi hiperinsektami. " + "Czy uda Ci się dotrzeć do serca roju, i zdobyć cenne królewskie mleczko?") + +S("This is what Hyperbug Queens eat. Very tasty and healthy.", + "Pożywienie Królowej Hiperinsektów, bardzo smaczne i zdrowe.") + +S("When you have this Orb, most monsters won't see you, unless " + "you are standing still, attacking, or picking up items.", + "Kiedy masz Sferę Niewidzialności, większość potworów Ciebie nie widzi, " + "chyba że stoisz w miejscu, atakujesz, albo podnosisz przedmioty.") + +Orb("Earth", "Ziemi") + +S("This orb lets you go through living walls. It also has powers in some of the other lands.", + "Ta sfera pozwala Ci przechodzić przez żywą ścianę. Ma też moce w niektórych z pozostałych krain.") + +// Land of Power + +N("Land of Power", GEN_F, "Kraina Mocy", "Krainy Mocy", "Krainą Mocy", "w Krainie Mocy") +N("Witch Apprentice", GEN_F, "Uczennica", "Uczennice", "Uczennicę", "Uczennicą") +N("Speed Witch", GEN_F, "Czarownica Szybka", "Czarownice Szybkie", "Czarownicę Szybką", "Czarownicą Szybką") +N("Flash Witch", GEN_F, "Czarownica Błysku", "Czarownice Błysku", "Czarownicę Błysku", "Czarownicą Błysku") +N("Fire Witch", GEN_F, "Czarownica Ognia", "Czarownice Ognia", "Czarownicę Ognia", "Czarownicą Ognia") +N("Aether Witch", GEN_F, "Czarownica Eteru", "Czarownice Eteru", "Czarownicę Eteru", "Czarownicą Eteru") +N("Winter Witch", GEN_F, "Czarownica Zimy", "Czarownice Zimy", "Czarownicę Zimy", "Czarownicą Zimy") +N("Evil Golem", GEN_M, "Zły Golem", "Złe Golemy", "Złego Golema", "Złym Golemem") +N("Powerstone", GEN_M, "Kamień Mocy", "Kamienie Mocy", "Kamień Mocy", "Kamieniem Mocy") +N("crystal cabinet", GEN_F, "kryształowa gablota", "kryształowe gabloty", "kryształową gablotę", "kryształową gablotą") + +S("When you have this Orb, you will leave a trail of fire behind you.", + "Kiedy masz Sferę Ognia, zostawiasz za sobą ognistą ścieżkę.") + +S( + "A Witch without any special powers. But watch out! She will " + "pick up any basic Orbs on her path, and use their powers.", + "Czarownica bez specjalnych mocy. Uważaj! Może ona podnieść " + "dowolną podstawową Sferę na swojej drodze, i użyć jej mocy.") + +S( "A Witch with a Speed spell. She moves twice as fast as you. Unless you " + "have an Orb of Speed too, of course!", + "Czarownica z czarem Szybkości. Rusza się dwa razy szybciej od Ciebie. " + "Chyba że Ty też masz Sferę Szybkości!") + +S( "A Witch with a Fire spell. She will leave a trail of fire behind her.", + "Czarownica z czarem Ogień. Zostawia za sobą płonącą ścieżkę.") + +S( "A Witch with a Winter spell. She is able to move through fire.", + "Czarownica z czarem Zima. Może przechodzić przez ogień.") + +S( "A Witch with an Aether spell. She is able to move through fire and walls.", + "Czarownica z czarem Eter. Może przechodzić przez ogień i ściany.") + +S( "Somebody has summoned these evil constructs with a magical process.", + "Wroga konstrukcja, tworzona poprzez magiczny proces.") + +S( "The Land of Power is filled with everburning fire, magical Orbs, and guarded by " + "witches and golems. There are basic orbs lying everywhere, and more prized ones " + "are kept in crystal cabinets.\n\n" + "Witches are allowed to use all the powers of the " + "basic orbs against intruders. These powers never expire, but a Witch " + "can use only one power at a time (not counting Orbs of Life).\n\n" + "Witches and Golems don't pursue you into other Lands. Also, most Orb powers" + "are drained when you leave the Land of Power.", + "Kraina Mocy jest wypełniona wiecznie płonącym ogniem, magicznymi Sferami, " + "i strzeżona przez Czarownice i golemy. Podstawowe Sfery walają się wszędzie, a " + "te bardziej cenne są trzymane w kryształowych gablotach.\n\n" + "Czarownice używają wszystkich mocy podstawowych Sfer przeciwko intruzom. " + "Ich moce nigdy nie przemijają, ale Czarownica może używać naraz tylko jednej " + "mocy (nie licząc Sfer Życia).\n\n" + "Czarownice i Golemy nie gonią Ciebie do innych krain. Większość Sfer " + "traci swoją moc, gdy opuszczasz Krainę Mocy.") + +S( + "Witches use these crystal cabinets to protect Powerstones, as well as the more " + "expensive Orbs. They are partially protected from thieves: they are too strong " + "to be smashed by conventional attacks, and if you try to steal the item " + "using an Orb of Aether, your Aether power will be completely drained.", + "Czarownice używają tych kryształowych gablot, by chronić Kamienie Mocy oraz bardziej " + "cenne Sfery. Gabloty są częściowo chronione przed kradzieżą: są zbyt mocne, " + "by je rozbić konwencjonalnymi atakami, a jeśli spróbujesz ukraść przedmiot " + "używając Sfery Eteru, Twoja moc Eteru zostanie całkowicie wyczerpana.") + +S( + "A Stone from the Land of Power. You are not sure what it is exactly, but " + "as the Powerstones are kept in crystal cabinets, they are surely valuable.", + "Kamień z Krainy Mocy. W sumie to nie wiesz, co to jest, ale trzymają te " + "kamienie w kryształowych gablotach, także musi być bardzo cenny.") + +Orb("Fire", "Ognia") + +// achievements: + +// x "Head Witch", "Have 10 Orbs active at the same time." +// "Enemy Number One", "Have an army of 1000 hyperbugs pursue you." +// x "Lifebringer", "Brought Life into the Dead Caves." +// "Wall Gardener", "Make a living wall grow outside of a cavernous region." +// x "Master Swordsman", "Defeat a Hedgehog Warrior, a Pikeman, and a Flail Guard at the same time." +// x "Master of Melee", "Defeat five monsters in melee at the same time." + +// for collection achievements: +// provide the required cases for descriptions: +// Spice, Royal Jelly, Silver, Powerstone, and Wine +// achievement names: +// Master of the Hive, Master of Power, Master of Vineyard, Master of Dead Caves, Master of the Mine +// "Hyperbug", "Hyperbug Warrior", "Hyperbug Queen", + +// for the store description: + +// (currently, five more lands are included!) + +// lines forgotten previously + +S("Your Aether power has expired! RUN!", "Twoja moc Eteru się wyczerpała! UCIEKAJ!") + +S("%The1 tricks %the2.", "%1 pokona%ł1 %a2.") +S("You trick %the1.", "Pokona%łeś0 %a1.") + +S( "A Witch with a Flash spell. Very dangerous!\n\nLuckily, she never uses the spell if it " + "would kill her friends. She could destroy an Evil Golem, though.", + "Czarownica z czarem Błysk. Bardzo niebezpieczna!\n\nNa szczęście, nie użyje swojego " + "czaru, jeśli by to zabiło jej przyjaciółki.") + +S("Your Aether powers are drained by %the1!", "Twoja moc Eteru została wyssana przez %a1!") +S("As you leave, your powers are drained!", "Opuszczasz Krainę Mocy... Twoja moc znikła!") +S("%The1 picks up %the2!", "%1 podniosła %a2!") // currently only Witches, so only female form + +S("You can right click any element to get more information about it.\n\n", + "Kliknij obiekt prawym przyciskiem myszy, by zobaczyć więcej informacji na jego temat.\n\n") + +S("TRANSLATIONWARNING", "") + +S("The Hyperbugs are fighting!", "Hiperinsekty ze sobą walczą!") + +S("","") N("",GEN_N,"","","","") + +S("Cheat-changed the display.", "Zmieniam tryb wyświetlania.") +S("Dead floor, with some rubble.", "Martwa ziemia, jest tu trochę gruzu.") + +// Camelot + +N("Camelot", GEN_O, "Camelot", "Camelot", "Camelot", "w Camelot") +N("wall of Camelot", GEN_F, "ściana Camelot", "ściany Camelot", "ścianę Camelot", "ścianą Camelot") +N("moat of Camelot", GEN_F, "fosa Camelot", "fosy Camelot", "fosę Camelot", "fosą Camelot") +N("Round Table", GEN_O, "Okrągły Stół", "Okrągłe Stoły", "Okrągły Stół", "Okrągłym Stołem") +N("Knight", GEN_M, "Rycerz", "Rycerze", "Rycerza", "Rycerzem") +N("Holy Grail", GEN_M, "Święty Graal", "Święte Graale", "Świętego Graala", "Świętym Graalem") + +S( + "The Knights of the Round Table are the greatest warriors of these lands. " + "They are not very inventive with names though, as they call each of their " + "castles Camelot. " + "You are probably worth of joining them, but they will surely give you " + "some quest to prove yourself...\n\n" + "Each castle contains a single treasure, the Holy Grail, in the center. " + "The radius of the Round Table is usually 28, but after you find a Holy Grail " + "successfully, each new castle (and each Round Table) you find will be bigger.", + + "Rycerze Okrągłego Stołu to najwięksi wojownicy tych krain. Niestety, nie są " + "zbyt pomysłowi w nazywaniu, i każdy swój zamek nazywają Camelot. " + "Prawdopodobnie nadajesz się, by stać się jednym z nich, ale na pewno " + "dadzą Ci jakąś misję, byś pokaza%ł0 swoją wartość...\n\n" + "Każdy zamek ma jeden skarb (Święty Graal) w samym środku. Promień Okrągłego " + "Stołu to normalnie 28, ale z każdym znalezionym Śwętym Graalem każdy nowy " + "zamek (i jego Okrągły Stół) będzie większy.") + +S("It would be impolite to land on the table!", + "Byłoby niegrzecznie wylądować na stole!") +S("You jump over the table!", "Skaczesz przez stół!") +S("That was not a challenge. Find a larger castle!", + "To nie było wyzwanie. Znajdź większy zamek!") +S("The Knights congratulate you on your success!", + "Rycerze gratulują Ci sukcesu!") +S("The Knights laugh at your failure!", + "Rycerze śmieją się z Twojej porażki!") +S("The Knights stare at you!", "Rycerze gapią się na Ciebie ze zdziwieniem!") +S("Come on, this is too easy... find a bigger castle!", + "Eee, to będzie za łatwe... znajdź większy zamek!") +S("The Knights wish you luck!", "Rycerze życzą powodzenia!") + +S("Congratulations! You have found the Holy Grail!", + "Gratulacje! Znalaz%łeś0 Świętego Graala!") + +S("\"I would like to congratulate you again!\"", "\"Pragnę jeszcze raz Ci pogratulować!\"") +S("\"Find the Holy Grail to become one of us!\"", "\"Znajdź Świętego Graala, by stać się jednym z nas!\"") +S("\"The Holy Grail is in the center of the Round Table.\"", "\"Święty Graal jest pośrodku Okrągłego Stołu.\"") +S("\"I enjoy watching the hyperbug battles.\"", "\"Lubię oglądać bitwy hiperinsektów.\"") +S("\"Have you visited a temple in R'Lyeh?\"", "\"By%łeś0 w świątyni w R'Lyeh?\"") +S("\"Nice castle, eh?\"", "\"Ładny zamek, co?\"") + +// Temple + +N("Temple of Cthulhu", GEN_F, "Świątynia Cthulhu", "Świątynie Cthulhu", "Świątynię Cthulhu", "w Świątyni Cthulhu") +N("big statue of Cthulhu", GEN_O, "pomnik Cthulhu", "pomniki Cthulhu", "pomnik Cthulhu", "pomnikiem Cthulhu") +N("Grimoire", GEN_F, "Księga", "Księgi", "Księgę", "Księgą") +N("Cult Leader", GEN_M, "Przywódca Kultu", "Przywódcy Kultu", "Przywódcę Kultu", "Przywódcą Kultu") + +S("The temple of Cthulhu consists of many concentric circles of columns. " + "You will surely encounter many Cultists there, who believe that a pilgrimage " + "to the inner circles will bring them closer to Cthulhu himself, and Grimoires " + "which surely contain many interesting secrets.\n\n" + "The circles in the temple of Cthulhu are actually horocycles. They are " + "infinite, and there is an infinite number of them.", + + "Świątynia Cthulhu składa się z wielu koncentrycznych kręgów kolumn. " + "Spotkasz tu wielu Kultystów, dla których pielgrzymka do wewnętrznych kręgów " + "to szansa na bycie bliżej Cthulhu, i Księgi zawierające wiele interesujących " + "sekretów.\n\n" + "Kręgi w Świątyni Cthulhu są właściwie horocyklami. Są nieskończone, i " + "jest ich nieskończenie wiele." + ) + +S("The Grimoires contain many secrets of the Great Old Ones. " + "Each new inner circle in the Temple of Cthulhu contains new Grimoires, with new secrets. " + "You hope to read them when you return home, and to learn many things. " + "The knowledge is valuable to you, but it is rather pointless to try to get " + "several copies of the same Grimoire...", + "Te Księgi zawierają tajemnice Wielkich Przedwiecznych. " + "Każdy krąg wewnętrzny w Świątyni Cthulhu zawiera nowe Księgi, z nowymi sekretami. " + "Zamierzasz je przeczytać po powrocie do domu. Wiedza jest dla Ciebe wartościowa, " + "ale nie ma sensu, by brać kilka kopii tej samej Księgi..." + ) + +S("These statues of Cthulhu are too large to carry, and they don't look too " + "valuable anyway. Most monsters will never go through them... they probably have " + "their reasons. But you can go! When you move into the cell containing " + "a statue, you push the statue to the cell you left.\n", + + "Te pomniki Cthulhu są za duże, by je nosić, zresztą i tak nie wyglądają " + "na zbyt cenne. Potwory nigdy przez nie nie przechodzą... pewnie mają swoje " + "powody. Ale Ty możesz przejść! Kiedy wchodzisz na pole z pomnikiem, " + "automatycznie przesuwasz pomnik na pole, które opuści%łeś0." + ) + +S("These Cultists can push the statues, just like you.", + "Ci kultyści mogą przesuwać pomniki, tak samo jak Ty.") + +S("You already have this Grimoire! Seek new tomes in the inner circles.", + "Już masz taką Księgę! Szukaj nowych tomów w wewnętrznych kręgach.") + +S("You push %the1 behind you!", "Popchn%ąłeś0 %a1 za siebie.") + +// More texts + +S("Your total kills", "Łączne zabicia") + +S( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count.", + + "W większości krain, zabijanie przeciwników pochodzących z danej krainy " + "powoduje, że generowane jest więcej skarbów. Ponadto, 100 zabić jest konieczne, " + "by móc znaleźć Cmentarz i Mrowisko.\n\n" + "Przyjazne stworzenia i części potworów (jak np. Bluszcz) występują na liście, " + "ale nie są liczone do łącznej liczby zabić.") + +S("There must be some temples of Cthulhu in R'Lyeh...", + "Muszą być jakieś świątynie Cthulhu w R'Lyeh...") + +S("You overheard Hedgehog Warriors talking about emeralds...", + "Podsłucha%łeś0 Jeże rozmawiające o szmaragdach...") + +S("You overhear miners talking about a castle...", + "Podsłucha%łeś0 górników rozmawiających o zamku...") + +S("A castle in the Crossroads...", "O zamku na Skrzyżowaniu...") + +/* +S("You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Po znalezieniu 5 Statuetek Cthulhu możesz w R'Lyeh trafić na Świątynie Cthulhu.") +*/ + +S("You have to escape first!", "Musisz najpierw uciec!"); +S("There is not enough space!", "Nie ma miejsca!"); + +S("Customize character", "pokoloruj postać") +S("gender", "płeć") + +// + +Orb("the Dragon", "Smoka") + +S("This Orb allows you to throw fire, just like the Fire Cultists.\n\n" + "Each fire drains 5 charges. You are not allowed to throw fire into adjacent cells.", + "Ta sfera pozwala Ci rzucać ogniem, tak jak Ogniści Kultyści. \n\n" + "Każdy rzucony ogień wymaga 5 ładunków. Nie możesz rzucać ogniem do sąsidenich " + "komórek." + ) + +S("You throw fire!", "Rzucasz ogniem!") + +Orb("Trickery", "Sztuczek") + +N("Illusion", GEN_F, "Iluzja", "Iluzje", "Iluzję", "Iluzją") + +S("This Orb allows you to create illusions of yourself. Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.\n\n" + "Each illusion takes 5 charges to create, and one extra charge " + "per turn. You can also click your illusion to take it away, restoring 4 charges.\n\n" + "If you have both Orb of Teleport and Orb of Trickery, Illusion is cast " + "first -- you can then teleport on your Illusion to switch places with it.", + "Ta sfera pozwala Ci tworzyć iluzje samego siebie. Większość potworów celuje w " + "iluzje, podobnie jak w Ciebie, Dudniki i Twoich przyjaciół.\n\n" + "Każda iluzja wymaga 5 ładunków do stworzenia, i jednego dodatkowego ładunku na " + "kolejkę. Możesz też kliknąć swoją iluzję by ją zabrać, co przywraca 4 ładunki.\n\n" + "Jeśli masz zarówno Sferę Teleportacji, jak i Sztuczek, Iluzja rzucana jest " + "jako pierwsza -- możesz następnie teleportować się na swoją iluzję, by się z nią " + "zamienić miejscami." + ) + +S("Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.", + "Większość potworów celuje w " + "iluzje, podobnie jak w Ciebie, Dudniki i Twoich przyjaciół.") + +S("You create an Illusion!", "Tworzysz iluzję!") +S("You take the Illusion away.", "Zabierasz iluzję!") + +S("You cannot target that far away!", "Nie możesz celować tak daleko!") +S("You cannot target that close!", "Nie możesz celować tak blisko!") +S("Cannot teleport on a monster!", "Nie możesz teleportować się na potwora!") +S("Cannot teleport on an item!", "Nie możesz teleportować się na przedmiot!") +S("Cannot teleport here!", "Nie możesz teleportować się tutaj!") +S("Cannot cast illusion on an item!", "Nie możesz rzucić iluzji na przedmiot!") +S("Cannot cast illusion here!", "Nie możesz rzucić iluzji tutaj!") +S("Cannot cast illusion on a monster!", "Nie możesz rzucić iluzji na potwora!") +S("Cannot throw fire there!", "Nie możesz tego podpalić!") + +// teleport -> target +// You cannot target that close! +#undef Orb + +S("or ESC to see how it ended", "lub ESC by zobaczyć, jak się skończyło") +S("high contrast", "wysoki kontrast") +S("draw the heptagons darker", "siedmiokąty ciemniejsze"); +S("targetting ranged Orbs Shift+click only", + "celowanie sfer na odgległość wymaga Shift+klik") +S("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.", + "Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, itd.") +S("also hold Alt during the game to toggle high contrast", + "Alt podczas gry przełącza wysoki kontrast") diff --git a/language-ru.cpp b/language-ru.cpp new file mode 100644 index 00000000..d3911481 --- /dev/null +++ b/language-ru.cpp @@ -0,0 +1,1460 @@ +// This translation file is encoded with UTF-8 + +// Nouns. + +// For each noun in English, provide: + +// 1) the type (usually gender) of the noun. For example, in Polish each noun can be: + +// masculine living (GEN_M), +// masculine object (GEN_O), +// feminine (GEN_F), or +// neuter (GEN_N). + +// 2) all the forms required by HyperRogue. For example, in Polish the following are +// given: +// The following forms are given: +// nominative (referred to as %1), +// nominative plural (%P1), +// accusative (%a1), +// ablative (%abl1) (for land names, locative "in/on..." is given instead of ablative). + +// Feel free to add more or less forms or types if needed. Note that you don't +// have to provide all the forms in your language, only those used by HyperRogue +// (in Polish just 4 of 14 forms are used, and this is probably similar in other +// languages). + +// monsters +N("Yeti", GEN_M, "Йети", "Йети", "Йети", "Йети") +N("Icewolf", GEN_M, "Ледяной волк", "Ледяные волки", "Ледяного волка", "Ледяным волком") +N("Ranger", GEN_M, "Странник", "Странники", "Странника", "Странником") +N("Rock Troll", GEN_M, "Горный тролль", "Горные тролли", "Горного Тролля", "Горным троллем") +N("Goblin", GEN_M, "Гоблин", "Гоблины", "Гоблина", "Гоблином") +N("Sand Worm", GEN_M, "Пустынный червь", "Пустынные черви", "Пустынного червя", "Пустынным червём") +N("Sand Worm Tail", GEN_M, "Хвост червя", "Хвосты червя", "Хвоста червя", "Хвостом червя") +N("Sand Worm W", GEN_M, "Пустынный червь W", "Пустынные черви W", "Пустынного червя W", "Пустынным червём W") +N("Desert Man", GEN_M, "Человек пустыни", "Люди пустыни", "Человека пустыни", "Человеком пустыни") +N("Ivy Root", GEN_O, "Корень плюща", "Корни плюща", "Корень плюща", "Корнем плюща") +N("Active Ivy", GEN_O, "Активный плющ", "Активные плющи", "Активный плющ", "Активным плющом") +N("Ivy Branch", GEN_F, "Ветвь плюща", "Ветви плюща", "Ветвь плюща", "Ветвью плюща") +N("Dormant Ivy", GEN_O, "Спящий плющ", "Спящие плющи", "Спящий плющ", "Спящим плющом") +N("Ivy N", GEN_O, "Плющ N", "Плющи N", "Плющ N", "Плющом N") +N("Ivy D", GEN_O, "Плющ D", "Плющи D", "Плющ D", "Плющом D") +N("Giant Ape", GEN_F, "Огромная обезьяна", "Огромные обезьяны", "Огромную обезьяну", "Огромной обезьяной") +N("Slime Beast", GEN_F, "Живая слизь", "Живая слизь", "Живую слизь", "Живой слизью") +N("Mirror Image", GEN_N, "Зеркальное отражение", "Зеркальные отражения", "Зеркальное отражение", "Зеркальным отражением") +N("Mirage", GEN_O, "Мираж", "Миражи", "Мираж", "Миражом") +N("Golem", GEN_M, "Голем", "Големы", "Голема", "Големом") +N("Eagle", GEN_M, "Орёл", "Орлы", "Орла", "Орлом") +N("Seep", GEN_M, "Горный призрак", "Горные призраки", "Горного призрака", "Горным призраком") +N("Zombie", GEN_M, "Зомби", "Зомби", "Зомби", "Зомби") +N("Ghost", GEN_M, "Дух", "Духи", "Духа", "Духом") +N("Necromancer", GEN_M, "Некромант", "Некроманты", "Некроманта", "Некромантом") +N("Shadow", GEN_F, "Тень", "Тени", "Тень", "Тенью") +N("Tentacle", GEN_N, "Щупальце", "Щупальца", "Щупальце", "Щупальцем") +N("Tentacle Tail", GEN_O, "Хвост щупальца", "Хвосты щупальца", "Хвост щупальца", "Хвостом щупальца") +N("Tentacle W", GEN_N, "Щупальце W", "Щупальца W", "Щупальце W", "Щупальцем W") +N("Tentacle (withdrawing)", GEN_N, "Щупальце (исчезает)", "Щупальца(исчезает)", "Щупальце(исчезает)", "Щупальцем(исчезает)") +N("Cultist", GEN_M, "Культист", "Культисты", "Культиста", "Культистом") +N("Fire Cultist", GEN_M, "Огненный культист", "Огненные культисты", "Огненного культиста", "Огненным культистом") +N("Greater Demon", GEN_M, "Старший демон", "Старшие демоны", "Старшего демона", "Старшим демоном") +N("Lesser Demon", GEN_M, "Младший демон", "Младшие демоны", "Младшего демона", "Младшим демоном") +N("Ice Shark", GEN_F, "Ледяная акула", "Ледяные акулы", "Ледяную акулу", "Ледяной акулой") +N("Running Dog", GEN_F, "Бегущая собака", "Бегущие собаки", "Бегущую собаку", "Бегущей собакой") +N("Demon Shark", GEN_F, "Акула-демон", "Акулы-демоны", "Акулу-демона", "Акулой-демоном") +N("Fire Fairy", GEN_F, "Огненная фея", "Огненный феи", "Огненную фею", "Огненной феей") +N("Crystal Sage", GEN_M, "Кристальный мудрец", "Кристальные мудрецы", "Кристального мудреца", "Кристальным мудрецом") +N("Hedgehog Warrior", GEN_M, "Ёж-воин", "Ежи-воины", "Ежа-воина", "Ежом-воином") +// items +N("Ice Diamond", GEN_O, "Ледяной алмаз", "Ледяные алмазы", "Ледяной алмаз", "Ледяным алмазом") +N("Gold", GEN_N, "Золото", "Золото", "Золото", "Золотом") +N("Spice", GEN_F, "Пряность", "Пряности", "Пряность", "Пряностью") +N("Ruby", GEN_O, "Рубин", "Рубины", "Рубин", "Рубином") +N("Elixir of Life", GEN_O, "Эликсир жизни", "Эликсиры жизни", "Эликсир жизни", "Эликсиром жизни") +N("Shard", GEN_O, "Осколок", "Осколки", "Осколок", "Осколком") +N("Necromancer's Totem", GEN_O, "Тотем некроманта", "Тотемы некроманта", "Тотем некроманта", "Тотемом некроманта") +N("Demon Daisy", GEN_F, "Адская ромашка", "Адские ромашки", "Адскую ромашку", "Адской ромашкой") +N("Statue of Cthulhu", GEN_F, "Статуя Ктулху", "Статуи Ктулху", "Статую Ктулху", "Статуей Ктулху") +N("Phoenix Feather", GEN_N, "Перо феникса", "Перья феникса", "Перо феникса", "Пером феникса") +N("Ice Sapphire", GEN_O, "Ледяной сапфир", "Ледяные сапфиры", "Ледяной сапфир", "Ледяным сапфиром") +N("Hyperstone", GEN_O, "Гиперкамень", "Гиперкамни", "Гиперкамень", "Гиперкамнем") +N("Key", GEN_O, "Ключ", "Ключи", "Ключ", "Ключом") +N("Dead Orb", GEN_F, "Мёртвая сфера", "Мёртвые сферы", "Мёртвую сферу", "Мёртвой сферой") +N("Fern Flower", GEN_O, "Цветок папоротника", "Цветы папоротника", "Цветок папоротника", "Цветком папоротника") +// orbs: we are using a macro here +#define Orb(E, P) N("Orb of "E, GEN_F, "Сфера "P, "Сферы "P, "Сферу "P, "Сферой "P) +Orb("Yendor", "Йендора") +Orb("Storms", "Бури") +Orb("Flash", "Вспышки") +Orb("Winter", "Зимы") +Orb("Speed", "Скорости") +Orb("Life", "Жизни") +Orb("Shielding", "Щита") +Orb("Teleport", "Телепорта") +Orb("Safety", "Безопасности") +Orb("Thorns", "Шипов") +// terrain features +N("none", GEN_N, "ничто", "ничто", "ничего", "ничем") +N("ice wall", GEN_F, "ледяная стена", "ледяные стены", "ледяную стену", "ледяной стеной") +N("great wall", GEN_F, "великая стена", "великие стены", "великую стену", "великой стеной") +N("red slime", GEN_F, "красная слизь", "красная слизь", "красную слизь", "красной слизью") +N("blue slime", GEN_F, "синяя слизь", "синяя слизь", "синюю слизь", "синей слизью") +N("living wall", GEN_F, "живая стена", "живые стены", "живую стену", "живой стеной") +N("living floor", GEN_O, "живой пол", "живые полы", "живой пол", "живым полом") +N("dead troll", GEN_M, "мёртвый тролль" ,"мёртвые тролли", "мёртвого тролля", "мёртвым троллем") +N("sand dune", GEN_F, "дюна", "дюны", "дюну", "дюной") +N("Magic Mirror", GEN_N, "Волшебное зеркало", "Волшебные зеркала", "Волшебное зеркало", "Волшебным зеркалом") +N("Cloud of Mirage", GEN_N, "Облако миражей", "Облака миражей", "Облако миражей", "Облаком миражей") +N("Thumper", GEN_O, "Тампер", "Тамперы", "Тампер", "Тампером") +N("Bonfire", GEN_O, "Костёр", "Костры", "Костёр", "Костром") +N("ancient grave", GEN_F, "древняя могила", "древние могилы", "древнюю могилу", "древней могилой") +N("fresh grave", GEN_F, "свежая могила", "свежие могилы", "свежую могилу", "свежей могилой") +N("column", GEN_F, "колонна", "колонны", "колонну", "колонной") +N("lake of sulphur", GEN_N, "озеро серы", "озёра серы", "озеро серы", "озером серы") +N("lake", GEN_N, "озеро", "озёра", "озеро", "озером") +N("frozen lake", GEN_N, "замёрзшее озеро", "замёрзшие озёра", "замёрзшее озеро", "замёрзшим озером") +N("chasm", GEN_F, "пропасть", "пропасти", "пропасть", "пропастью") +N("big tree", GEN_N, "большое дерево", "большие деревья", "большое дерево", "большим деревом") +N("tree", GEN_N, "дерево", "деревья", "дерево", "деревом") +// lands +N("Great Wall", GEN_F, "Великая стена", "Великие стены", "Великую стену", "на Великой стене") +N("Crossroads", GEN_O, "Перекрёсток", "Перекрёстки", "Перекрёсток", "на Перекрёстке") +N("Desert", GEN_F, "Пустыня", "Пустыни", "Пустыню", "в Пустыне") +N("Icy Land", GEN_F, "Ледяная земля", "Ледяные земли", "Ледяную землю", "в Ледяной земле") +N("Living Cave", GEN_F, "Живая Пещера", "Живые Пещеры", "Живую Пещеру", "в Живой Пещере") +N("Jungle", GEN_N, "Джунгли", "Джунгли", "Джунгли", "в Джунглях") +N("Alchemist Lab", GEN_F, "Лаборатория", "Лаборатории", "Лабораторию", "в Лаборатории") +N("Mirror Land", GEN_F, "Зеркальная земля", "Зеркальные земли", "Зеркальную землю", "в Зеркальной земле") +N("Graveyard", GEN_N, "Кладбище", "Кладбища", "Кладбище", "на Кладбище") +N("R'Lyeh", GEN_O, "Р'Льех", "Р'Льех", "Р'Льех", "в Р'Льехе") +N("Hell", GEN_O, "Ад", "Ад", "Ад", "в Аду") +N("Cocytus", GEN_O, "Коцит", "Коцит", "Коцит", "в Коците") +N("Land of Eternal Motion", GEN_F, "Земля Вечного Движения", "Земли Вечного Движения", "Землю Вечного Движения", "в Земле Вечного Движения") +N("Dry Forest", GEN_O, "Сухой Лес", "Сухие Леса", "Сухой Лес", "в Сухом Лесу") +N("Game Board", GEN_F, "Игровая Доска", "Игровые Доски", "Игровую Доску", "на Игровой Доске") + +// Game messages + +// fighting messages + +// For each English form, provide a Polish form. Player is referred to via %...0, +// and objects are referred to via %...1 and %...2. For example, in Polish: + +// %a1 refers to the accusative form of the first object (as explained above in 'Nouns') +// likewise, %a2 refers to the accusative form of the second object +// %E1 is replaced by "Е‚", "Е‚o" or "Е‚a", depending on the gender of %1 +// %EeЕ›0 adds "Е‚eЕ›" or "Е‚aЕ›" depending on the gender of the player + +// Use whatever %xxx# codes you need for your language. Of course, +// tell me how your codes should be expanded. + +S("You kill %the1.", "Вы убили %a1.") +S("You would be killed by %the1!", "Вас убьёт %1!") +S("%The1 would get you!", "%1 уничтожит вас здесь!") +S("%The1 destroys %the2!", "%1 уничтожил%E1 %a2!") +S("%The1 eats %the2!", "%1 съел%E1 %a2!") +S("The ivy destroys %the1!", "Плющ уничтожил %a1!") +S("%The1 claws %the2!", "%1 атаковал%E1 %a2!") +S("%The1 scares %the2!", "%1 пугает %a2!") +S("%The1 melts away!", "%1 тает!") +S("%The1 stabs %the2.", "%1 заколол%E1 %a2.") +S("You stab %the1.", "Вы закололи %a1.") + +S("You cannot attack %the1 directly!", "Вы не можете напасть на %a1!") +S("Stab them by walking around them.", "Нападите на него сбоку.") + +S("You feel more experienced in demon fighting!", "Теперь Вы более опытны в борьбе с демонами!") +S("Cthulhu withdraws his tentacle!", "Ктулху забирает свой щупальце!") +S("The sandworm explodes in a cloud of Spice!", "Червь взорвался и стал облаком специй") +S("%The1 is confused!", "%1 в замешательстве") +S("%The1 raises some undead!", "%1 восстал из мёртвых!") +S("%The1 throws fire at you!", "%1 бросил в Вас огнём!") +S("%The1 shows you two fingers.", "%1 показал%E1 Вам два пальца.") +S("You wonder what does it mean?", "Вы спросите, а что это значит?") +S("%The1 shows you a finger.", "%1 показал%E1 Вам палец.") +S("You think about possible meanings.", "Вы думаете о возможном значении.") +S("%The1 moves his finger downwards.", "%1 опустил%E1 свои пальцы.") +S("Your brain is steaming.", "Ваш мозг дымится.") +S("%The1 destroys %the2!", "%1 уничтожил%E1 %a2!") +S("You join %the1.", "Вы встретились с %abl1.") +S("Two of your images crash and disappear!", "Два Ваших двойника столкнулись и уничтожились!") +S("%The1 breaks the mirror!", "%1 разбил%E1 зеркало!") +S("%The1 disperses the cloud!", "%1 рассеял%E1 облако!") +S("You activate the Flash spell!", "Вы активировали заклинание вспышки!") +S("You activate the Lightning spell!", "Вы активировали заклинание молнии!") +S("Ice below you is melting! RUN!", "Лёд под Вами тает! БЕГИТЕ!") +S("This spot will be burning soon! RUN!", "Земля под Вами загорается! БЕГИТЕ!") +S("The floor has collapsed! RUN!", "Пол рухнул! БЕГИТЕ!") +S("You need to find the right Key to unlock this Orb of Yendor!", + "Вам нужен ключ, чтобы открыть сферу Йендора!") +S("You fall into a wormhole!", "Вы упали в червоточину!") +S("You activate %the1.", "Вы активировали %a1.") +S("No room to push %the1.", "Нет места, чтобы толкать %a1.") +S("You push %the1.", "Вы толкнули %a1.") +S("You start cutting down the tree.", "Вы начали рубить дерево.") +S("You cut down the tree.", "Вы срубили дерево.") +S("You cannot attack Sandworms directly!", "Вы не можете атаковать песчаных червей!") +S("You cannot attack Tentacles directly!", "Вы не можете атаковать щупальца Ктулху!") +S("You cannot defeat the Shadow!", "Вы не можете убить свою тень!") +S("You cannot defeat the Greater Demon yet!", "Вы пока не можете победить Старшего демона!") +S("That was easy, but groups could be dangerous.", "Они слабы, но в стае могут быть опасны.") +S("Good to know that your fighting skills serve you well in this strange world.", "Полезно знать, что Ваши боевые навыки неплохо работают в этом странном мире.") +S("You wonder where all these monsters go, after their death...", "Вы задаётесь вопросом, куда же деваются эти монстры после смерти?") +S("You feel that the souls of slain enemies pull you to the Graveyard...", "Вы чувствуете, как души убитых врагов тянут Вас на Кладбище.") +S("Wrong color!", "Не тот цвет!") +S("You cannot move through %the1!", "Вы не можете пройти через %a1!") +S("%The1 would kill you there!", "%1 убьёт Вас здесь!") +S("Wow! %1! This trip should be worth it!", "%1! А это путешествие стоит того!") +S("For now, collect as much treasure as possible...", "Соберите столько сокровищ, сколько сможете...") +S("Prove yourself here, then find new lands, with new quests...", "Проверь себя здесь, а потом ищи новые земли с новыми миссиями") +S("You collect your first %1!", "Вы нашли перв%A1 %a1!") +S("You have found the Key! Now unlock this Orb of Yendor!", "Вы нашли ключ! Откройте им сферу Йендора!") +S("This orb is dead...", "Эта сфера мертва...") +S("Another Dead Orb.", "Ещё одна мёртвая сфера.") +S("You have found %the1!", "Вы нашли %a1!") +S("You feel that %the2 become%s2 more dangerous.", "Вы чувствуете, что находиться %abl2 всё опаснее.") +S("With each %1 you collect...", "С каждым собранным %abl1...") +S("Are there any magical orbs in %the1?...", "Есть ли какие-нибудь сферы %abl1?") +S("You feel that %the1 slowly become%s1 dangerous...", "Вы чувствуете, что %1 становится всё опаснее...") +S("Better find some other place.", "Лучше отправьтесь в другое место.") +S("You have a vision of the future, fighting demons in Hell...", "Вы видите себя в будущем, убивающего демонов в Аду...") +S("With this Elixir, your life should be long and prosperous...", "С этим эликсиром Ваша жизнь будет долгой и процветающей...") +S("The Necromancer's Totem contains hellish incantations...", "Тотем некроманта содержит адские заклинания...") +S("The inscriptions on the Statue of Cthulhu point you toward your destiny...", "Надписи на статуе Ктулху показывают Вам Вашу судьбу...") +S("Still, even greater treasures lie ahead...", "Большая часть сокровищ ещё впереди...") +S("You collect %the1.", "Вы нашли %a1.") +S("CONGRATULATIONS!", "ПОЗДРАВЛЯЕМ!") +S("Collect treasure to access more different lands...", "Собирайте сокровища, чтобы найти новые земли...") +S("You feel that you have enough treasure to access new lands!", "Вы чувствуете, что у Вас достаточно сокровищ, чтобы открыть новые земли!") +S("Collect more treasures, there are still more lands waiting...", "Собирайте больше сокровищ, ещё много земель Вас ждут...") +S("You feel that the stars are right, and you can access R'Lyeh!", "Вы чувствуете, что звёзды правы, Вы можете открыть Р'Льех!") +S("Kill monsters and collect treasures, and you may get access to Hell...", "Убивайте монстров и собирайте сокровища, и Вы сможете открыть Ад...") +S("To access Hell, collect 10 treasures each of 9 kinds...", "Чтобы открыть Ад, соберите по 10 сокровищ из 9 различных мест...") +S("Abandon all hope, the gates of Hell are opened!", "Оставь надежду, врата Ада открылись!") +S("And the Orbs of Yendor await!", "Шары Йендора ждут!") +S("You switch places with %the1.", "Вы поменялись местами с %abl1.") +S("You rejoin %the1.", "Вы воссоединились с %abl1.") +S("The mirror shatters!", "Зеркало разбилось!") +S("The cloud turns into a bunch of images!", "Облако превратилось в группу изображений!") +S("The slime reacts with %the1!", "Слизь реагирует с %abl1!") +S("You drop %the1.", "Вы выкинули %a1.") +S("You feel great, like a true treasure hunter.", "Вы чувствуете себя как прекрасный охотник за сокровищами.") +S("Your eyes shine like gems.", "Ваши глаза сияют, как драгоценные камни.") +S("Your eyes shine as you glance at your precious treasures.", "Ваши глаза сверкают, когда Вы смотрите на свои драгоценности.") +S("You glance at your great treasures.", "Вы смотрите на ваши громадные сокровища.") +S("You glance at your precious treasures.", "Вы смотрите на ваши драгоценные сокровища.") +S("You glance at your precious treasure.", "Вы смотрите на ваше драгоценное сокровище.") +S("Your inventory is empty.", "Ваш инвентарь пуст.") +S("You teleport to a new location!", "Вы телепортировались в новое место!") +S("Could not open the score file: ", "Невозможно открыть файл с результатами: ") +S("Game statistics saved to %1", "Статистика игры записана в %1") +S("Game loaded.", "Игра сохранена.") +S("You summon some Mimics!", "Вы призвали миражи!") +S("You summon a golem!", "Вы призвали голема!") +S("You will now start your games in %1", "Теперь вы начинаете игру %abl1") +S("Activated the Hyperstone Quest!", "Активирована миссия Гиперкамней!") +S("Orb power depleted!", "Сила сферы исчерпана!") +S("Orbs summoned!", "Сферы призваны!") +S("Orb power gained!", "Сила сферы получена!") +S("Dead orbs gained!", "Мёртвые сферы получены!") +S("Orb of Yendor gained!", "Сферы Йендора получены!") +S("Treasure gained!", "Сокровища получены!") +S("Lots of treasure gained!", "Много сокровищ получено!") +S("You summon a sandworm!", "Вы призвали червя!") +S("You summon an Ivy!", "Вы призвали плющ!") +S("You summon a monster!", "Вы призвали монстра!") +S("You summon some Thumpers!", "Вы призвали тамперы!") +S("You summon a bonfire!", "Вы призвали костры!") +S("Treasure lost!", "Сокровища потеряны!") +S("Kills gained!", "Убийства получены!") +S("Activated Orb of Safety!", "Активирована сфера безопасности!") +S("Teleported to %1!", "Вы телепортированы %abl1") + +S("Welcome to HyperRogue", "Добро пожаловать в HyperRogue") +S(" for Android", " на Android") +S(" for iOS", " на iOS") +S("! (version %1)\n\n", "! (версия %1)\n\n") +S(" (press ESC for some hints about it).", " (нажмите ESC, чтобы получить подсказки).") +S("Press 'c' for credits.", "Нажмите 'c', чтобы узнать авторов.") +S("game design, programming, texts and graphics by Zeno Rogue \n\n", + "проект, программирование, тексты и графика: Zeno Rogue \n\n") +S("add credits for your translation here", "Перевод: green orange \n\n") +S(" (touch to activate)", " (коснитесь, чтобы активировать)") +S(" (expired)", " (кончился)") +S(" [%1 turns]", " [ходов: %1]") +S(", you", ", Вы") +S("0 = Klein model, 1 = Poincaré model", "0 = модель Клейна, 1 = модель Пуанкаре") +S("you are looking through it!", "взгляните на гиперболоид!") +S("simply resize the window to change resolution", "просто поменяйте размер окна чтобы сменить разрешение") +S("[+] keep the window size, [-] use the screen resolution", "[+] фиксирует размер окна, [-] использует разрешение экрана") +S("+5 = center instantly, -5 = do not center the map", "+5 = центрировать сразу, -5 = не центрировать") +S("press Space or Home to center on the PC", "Нажмите Пробел или Home, чтобы отцентрировать экран на персонаже.") +S("You need special glasses to view the game in 3D", "Вам нужны специальные очки, чтобы видеть игру в 3D") +S("You can choose one of the several modes", "Вы можете выбрать один из нескольких режимов") +S("ASCII", "ASCII") +S("black", "чёрный") +S("plain", "простой") +S("Escher", "Эшер") +S("items only", "только предметы") +S("items and monsters", "предметы и монстры") +S("no axes", "без осей") +S("auto", "авто") +S("light", "легкий") +S("heavy", "тяжёлый") +S("The axes help with keyboard movement", "Оси помогают перемещаться с помощью клавиатуры") +S("Config file: %1", "Файл конфигурации: %1") +S("joystick mode: automatic (release the joystick to move)", "Режим джойстика: авто (опустите джойстик для перемещения)") +S("joystick mode: manual (press a button to move)", "Режим джойстика: ручной (нажмите на клавишу для перемещения)") +S("Reduce the framerate limit to conserve CPU energy", "Ограничить fps, чтобы сохранить энергию ЦП") +S("Press F1 or right click for help", "Нажмите F1 или ПКМ для помощи") +//"Нажмите F1 или правую кнопку мыши для получения помощи") +S("No info about this...", "Нет информации об этом...") +S("Press Enter or F10 to save", "Нажмите Enter или F10, чтобы сохраниться") +S("Press Enter or F10 to quit", "Нажмите Enter или F10, чтобы выйти") +S("or 'r' or F5 to restart", "либо 'r' или F5, чтобы начать заново") +S("or 't' to see the top scores", "либо 't', чтобы посмотреть результаты") +S("or another key to continue", "либо другую клавишу, чтобы продолжить") +S("It is a shame to cheat!", "Как Вам не стыдно!") +S("Showoff mode", "Режим показа") +S("Quest status", "Статус миссии") +S("GAME OVER", "КОНЕЦ ИГРЫ") +S("Your score: %1", "Ваш счёт: %1") +S("Enemies killed: %1", "Врагов убито: %1") +S("Orbs of Yendor found: %1", "Собрано сфер Йендора: %1") +S("Collect 30 $$$ to access more worlds", "Соберите 30 $$$, чтобы открыть новые земли") +S("Collect at least 10 treasures in each of 9 types to access Hell", "Соберите хотя бы по 10 сокровищ 9 разных типов, чтобы попасть в Ад") +S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Соберите 10 адских ромашек, чтобы найти сферу Йендора") +S("Hyperstone Quest: collect at least 10 %1 in %the2", "Миссия Гиперкамня: соберите 10 драгоценностей в %abl2") +S("Hyperstone Quest completed!", "Миссия Гиперкамня закончена!") +S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Ищите сферы Йендора в Аду и на Перекрёстке!") +S("Unlock the Orb of Yendor!", "Откройте сферу Йендора!") +S("Defeat 100 enemies to access the Graveyard", "Убейте 100 врагов, чтобы открыть Кладбище") +S("(press ESC during the game to review your quest)", "(нажмите ESC во время игры, чтобы посмотреть ваши миссии)") +S("you have cheated %1 times", "количество читов: %1") +S("%1 turns (%2)", "ходов: %1 (%2)") +S("last messages:", "последние сообщения: ") +S("time elapsed", "время") +S("date", "дата") +S("treasure collected", "собрано сокровищ") +S("total kills", "всего убийств") +S("turn count", "ходов потрачено") +S("cells generated", "клеток сгенерировано") +S("t/left/right - change display, up/down - scroll, s - sort by", "t/левая/правая стрелки - изменить, вверх/вниз - листать, s - сортировать") +S("kills", "убийств") +S("time", "время") +S("ver", "версия") +S("SORT", "СОРТИРОВКА") +S("PLAY", "ИГРА") +S("Your total wealth", "Ваше богатство") +S("treasure collected: %1", "собрано сокровищ: %1") +S("objects found: %1", "найдено предметов: %1") +S("orb power: %1", "сила сферы: %1") +S(" (click to drop)", " (нажмите, чтобы бросить)") +S("You can also scroll to the desired location and then press 't'.", "Вы также можете пролистать в нужное месть и нажать 't'.") +S("Thus, it is potentially useful for extremely long games, which would eat all the memory on your system otherwise.\n", + "Это может быть полезно для крайне долгих игр, если у Вас заканчивается память.") +S("You can touch the Dead Orb in your inventory to drop it.", "Коснитесь мёртвой сферы, чтобы собрать её.") +S("This might be useful for Android devices with limited memory.", "Это может быть полезно для Android-устройств с ограниченной памятью.") +S("You can press 'g' or click them in the list to drop a Dead Orb.", "Вы можете нажать 'g' либо кликнуть на сферу в списке, чтобы бросить её.") +S("frames per second", "кадров в секунду") +S("monsters killed: %1", "монстров убито: %1") +S("Drawing %1 (layer %2), F1 for help", "Рисуем %1 (слой %2), F1 - помощь") +S("hepta floor", "семиугольный пол") +S("hexa floor", "шестиугольный пол") +S("character", "персонаж") +S("ESC for menu/quest", "ESC - меню/миссия") +S("vector graphics editor", "векторный графический редактор") +S("cheat mode", "режим обманщика") +S("heptagonal game board", "семиугольная игровая доска") +S("triangular game board", "треугольная игровая доска") +S("HyperRogue game board", "игровая доска HyperRogue") +S("first page [Space]", "первая страница [пробел]") +S("exit configuration", "выйти из настроек") +S("Configuration:", "Настройки:") +S("video resolution", "видео разрешение") +S("fullscreen mode", "полноэкранный режим") +S("animation speed", "скорость анимации") +S("dist from hyperboloid ctr", "расстояние от центра гиперболоида") +S("scale factor", "масштаб") +S("wall display mode", "режим показа стен") +S("monster display mode", "режим показа монстров") +S("cross display mode", "режим показа осей") +S("background music volume", "громкость фоновой музыки") +S("OFF", "ВЫКЛ") +S("ON", "ВКЛ") +S("distance between eyes", "расстояние между глазами") +S("framerate limit", "ограничение на fps") +S("joystick mode", "режим джойстика") +S("automatic", "авто") +S("manual", "ручной") +S("language", "язык") +S("EN", "RU") +S("player character", "Ваш персонаж") +S("male", "мужской") +S("female", "женский") +S("use Shift to decrease and Ctrl to fine tune ", "используйте Shift для уменьшения,") +S("(e.g. Shift+Ctrl+Z)", "Ctrl для тонкой настройки") // (например, Shift+Ctrl+Z)") +S("the second page [Space]", "вторая страница [Пробел]") +S("special features [Space]", "специальные опции [Пробел]") +S("exit configuration", "выйти из настроек") +S("see the help screen", "смотри экран помощи") +S("save the current config", "сохранить текущие настройки") +S("(v) config", "(v) настр.") +S("Screenshot saved to %1", "Скриншот сохранён в %1") +S("You need an Orb of Teleport to teleport.", "Вам нужна сфера телепорта для телепортации.") +S("Use arrow keys to choose the teleport location.", "С помощью стрелок выберите место для телепортации.") +S("openGL mode enabled", "режим OpenGL включен") +S("openGL mode disabled", "режим OpenGL выключен") +S("openGL & antialiasing mode", "openGL и режим сглаживания") +S("anti-aliasing enabled", "сглаживание включено") +S("anti-aliasing disabled", "сглаживание выключено") +S("You activate your demonic powers!", "Вы активировали свои демонические силы!") + +// Steam achievement messages + +S("New Achievement:", "Новое достижение:") +S("Your total treasure has been recorded in the Steam Leaderboards.", "Ваш общий результат занесён в таблицу Steam.") +S("Congratulations!", "Поздравляем!") +S("You have improved your total high score and %1 specific high scores!", "Вы подняли свой общий результат и %1 отдельных результатов!") +S("You have improved your total and '%1' high score!", "Вы подняли свой общий результат и '%1'!") +S("You have improved your total high score on Steam. Congratulations!", "Вы увеличили свой общий счёт в Steam. Поздравляем!") +S("You have improved %1 of your specific high scores!", "Вы увеличили %1 отдельных результатов!!") +S("You have improved your '%1' high score on Steam!", "Вы подняли свой счёт в категории '%1' в Steam!") +S("You have collected 10 treasures of each type.", "Вы собрали по 10 сокровищ каждого типа.") +S("This is your first victory!", "Это ваша первая победа!") +S("This has been recorded in the Steam Leaderboards.", "Это записано в таблицу рекордов Steam.") +S("The faster you get here, the better you are!", "Чем быстрее, тем лучше!") +S("You have improved both your real time and turn count. Congratulations!", "Вы улучшили результаты по реальному времени и по числу ходов! Поздравляем") +S("You have used less real time than ever before. Congratulations!", "Вы потратили меньше реального времени, чем раньше. Поздравляем!") +S("You have used less turns than ever before. Congratulations!", "Вы потратили меньше ходов, чем раньше. Поздравляем!") + +// help texts. These are separated into multiple lines just for convenience, +// you don't have to follow. + +S( + "You have been trapped in a strange, non-Euclidean world. Collect as much treasure as possible " + "before being caught by monsters. The more treasure you collect, the more " + "monsters come to hunt you, as long as you are in the same land type. The " + "Orbs of Yendor are the ultimate treasure; get at least one of them to win the game!", + + "Вы оказались заперты в странном неевклидовом мире. Соберите как можно больше сокровищ " + "перед тем как Вас поймают монстры. Чем больше сокровищ Вы собираете, тем больше монстров " + "на Вас охотится, пока Вы находитесь на одной территории. Сферы Йендора - уникальные " + "сокровища; соберите хотя бы одну, чтобы выиграть!" + ) + +S( + "You can fight most monsters by moving into their location. " + "The monster could also kill you by moving into your location, but the game " + "automatically cancels all moves which result in that.\n\n", + + "Вы можете атаковать большинство монстров, просто передвигаясь на клетку с ними. " + "Монстры могут атаковать Вас тем же способом, но игра сама блокирует ходы, " + "приводящие к этому.\n\n") + +S( + "Usually, you move by touching somewhere on the map; you can also touch one " + "of the four buttons on the map corners to change this (to scroll the map " + "or get information about map objects). You can also touch the " + "numbers displayed to get their meanings.\n", + "Обычно Вы перемещаетесь просто кликая мышкой в нужном направлении; на можно " + "использовать 4 кнопки по углам карты чтобы листать карту или получать" + "информацию про объекты. Кликая по изображаемым числам, можно смотреть, " + "что они означают.\n") + +S("Move with mouse, num pad, qweadzxc, or hjklyubn. Wait by pressing 's' or '.'. Spin the world with arrows, PageUp/Down, and Home/Space. " + "To save the game you need an Orb of Safety. Press 'v' for config, ESC for the quest status and menu.\n\n", + "Двигайтесь с помощью мышки, нумпада, qweadzxc или hjklyubn. Ждите, нажимая 's' или '.'. " + "Поворачивайте карту стрелками, PageUp/Down или Home/Space. " + "Чтобы сохраниться, Вам нужна сфера безопасности. Нажмите 'v' для настроек, Esc для статуса квеста или меню.") + +S("See more on the website: ", "Смотрите далее на сайте: ") + +S("special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n", + "отдельное спасибо следующим людям за багрепорты, предложения и другую помощь:\n\n%1\n\n") + +S( + "The total value of the treasure you have collected.\n\n" + "Every world type contains a specific type of treasure, worth 1 $$$; " + "your goal is to collect as much treasure as possible, but every treasure you find " + "causes more enemies to hunt you in its native land.\n\n" + "Orbs of Yendor are worth 50 $$$ each.\n\n", + + "Общая стоимость найденных Вами сокровищ.\n\n" + "Каждая земля содержит свой тип ценности, стоящей 1 $$$; " + "Ваша цель - собрать как можно больше ценностей, но каждая найденная ценность " + "увеличивает количество врагов в этой земле.\n\n" + "Сфера Йендора стоит 50 $$$.\n\n") + +S( + "The higher the number, the smoother the animations in the game. " + "If you find that animations are not smooth enough, you can try " + "to change the options ", + "Чем выше это число, тем более гладкой будет анимация в игре. " + "Если она недостаточно гладкая, поменяйте настройки. ") + +S("(Menu button) and select the ASCII mode, which runs much faster. " + "Depending on your device, turning the OpenGL mode on or off might " + "make it faster, slower, or cause glitches.", + "(Меню), выберите ASCII режим, который работает быстрее. В зависимости " + "от Вашего устройства включите или выключите OpenGL. Он может быть " + "как быстрее, так и медленнее. " + ) + +S("(in the MENU). You can reduce the sight range, this should make " + "the animations smoother.", + "(в MENU). Вы можете уменьшить радиус обзора, что сделает анимацию более гладкой. ") + +S("(press v) and change the wall/monster mode to ASCII, or change " + "the resolution.", + "(нажмите 'v') и поменяйте режим отображения стен/монстров на ASCII, или измените разрешение. ") + +S( + "In this mode you can draw your own player character and floors. " + "Mostly for the development purposes, but you can have fun too.\n\n" + "f - floor, p - player (repeat 'p' for layers)\n\n" + "n - new shape, u - copy the 'player body' shape\n\n" + "1-9 - rotational symmetries, 0 - toggle axial symmetry\n\n" + "point with mouse and: a - add point, m - move nearest point, d - delete nearest point, c - nearest point again, b - add after nearest\n\n" + "s - save in C++ format (but cannot be loaded yet without editing source)\n\n" + "z - zoom, o - Poincaré model\n", + + "В этом режиме Вы можете рисовать персонажа и всё окружение. " + "В основном для нужд разработчиков, но и просто для веселья тоже.\n\n" + "f - пол, p - игрок (повторите для смены слоя)\n\n" + "n - новая форма, u - копировать форму игрока\n\n" + "1-9 - повороты, 0 - осевая симметрия\n\n" + "Расставьте точки мышкой и: a - добавить точку, m - двигать ближайшую точку, d - удалить ближайшую точку, c - снова ближайшая точка, b - после ближайшей\n\n" + "s - запись в формате C++ (пока не может быть загружено без редактирования исходников)\n\n" + "z - увеличение, o - модель Пуанкаре\n") + +S( + "These huge monsters normally live below the sand, but your movements have " + "disturbed them. They are too big to be slain with your " + "weapons, but you can defeat them by making them unable to move. " + "This also produces some Spice. They move two times slower than you.", + + "Эти огромные монстры обычно живут под огромным слоем песка, но Вы их потревожили. " + "Они слишком велики, чтобы их можно было убить Вашим оружием, но они " + "умирают, если не могут двигаться. Также они производят пряности. Они движутся в 2 раза медленнее Вас.") + +S("The tentacles of Cthulhu are like sandworms, but longer. " + "They also withdraw one cell at a time, instead of exploding instantly.", + + "Щупальца Ктулху походи на песчаных червей, но длиннее. " + "Они втягиваются по одной клетке, а не взрываются мгновенно.") + +S( + "A huge plant growing in the Jungle. Each Ivy has many branches, " + "and one branch grows per each of your moves. Branches grow in a clockwise " + "order. The root itself is vulnerable.", + "Огромное растение, растущее в Джунглях. Каждый плющ имеет много побегов, " + "и один из них растёт каждый ход. Побеги растут по часовой стрелке. Корень " + "плюща - самое уязвимое место.\n") + +S("The Alchemists produce magical potions from pools of blue and red slime. You " + "can go through these pools, but you cannot move from a blue pool to a red " + "pool, or vice versa. Pools containing items count as colorless, and " + "they change color to the PC's previous color when the item is picked up. " + "Slime beasts also have to keep to their own color, " + "but when they are killed, they explode, destroying items and changing " + "the color of the slime and slime beasts around them.", + "Алхимики создают магические зелья из красной и синей слизи. Вы " + "можете перемещаться по этой слизи, но не можете перейти с красной на синюю " + "и наоборот. Слизь, содержащая предметы, бесцветна и меняет свой цвет на Ваш, " + "когда Вы собираете предмет. Живая слизь тоже двигается лишь по своему цвету, " + "но при гибели меняет цвет всей слизи в радиусе 2 клеток на свой.\n") + +S( + "These creatures are slow, but very powerful... more powerful than you. " + "You need some more experience in demon fighting before you will be able to defeat them. " + "Even then, you will be able to slay this one, but more powerful demons will come...\n\n" + "Each 10 lesser demons you kill, you become powerful enough to kill all the greater " + "demons on the screen, effectively turning them into lesser demons.", + + "Эти существа медленны, но очень сильны... гораздо сильнее Вас. " + "Вам нужно набраться опыта в битве с демонами.\n\n" + "Когда Вы убьёте 10 младших демонов, Вы станете достаточно сильны, чтобы побеждать старших, " + "которые тут же сами станут младшими, но потом придут новые старшие демоны...") + +S("These creatures are slow, but they often appear in large numbers.", + "Эти существа медленны, но они берут количеством.") + +S("A big monster from the Living Caves. A dead Troll will be reunited " + "with the rocks, causing some walls to grow around its body.", + "Огромный монстр из Живых пещер. Мёртвый тролль окружается " + "камнями, вызывая рост скал вокруг себя.") + +S("Huge, impassable walls which separate various lands.", + "Огромные непроходимые стены, разделяющие разные земли.") + +S( + "This cave contains walls which are somehow living. After each turn, each cell " + "counts the number of living wall and living floor cells around it, and if it is " + "currently of a different type than the majority of cells around it, it switches. " + "Items count as three floor cells, and dead Trolls count as five wall cells. " + "Some foreign monsters also count as floor or wall cells.\n", + "В этой пещере даже стены живые. Каждый ход каждая клетка считает количество " + "клеток живого пола и живых стен среди соседних, и если клеток другого типа больше, " + "она меняет тип. Предметы считаются за 3 клетки пола, " + "мёртвые тролли - за 5 клеток стен.Некоторые монстры из других земель " + "тоже могут считаться за пол или стены.\n") + +// "клеток живого пола и живых стен среди соседних‚ и если клеток другого типа больше, " + +S( + "This forest is quite dry. Beware the bushfires!\n" + "Trees catch fire on the next turn. The temperature of the grass cells " + "rises once per turn for each fire nearby, and becomes fire itself " + "when its temperature has risen 10 times.\n" + "You can also cut down the trees. Big trees take two turns to cut down.", + "Этот лес довольно сухой. Берегитесь лесных пожаров!\n" + "Деревья загораются от огня на следующем шагу. Температура травы растёт " + "на каждом шаге, после 10 шагов трава загорается.\n" + "Также Вы можете рубить деревья. Большие деревья требуют двух ударов." + ) + +S("A big and quite intelligent monster living in the Icy Land.", + "Большой и довольно умный монстр из Ледяной земли.") + +S( + "A nasty predator from the Icy Land. Contrary to other monsters, " + "it tracks its prey by their heat.", + "Мерзкий хищник из Ледяной земли. В отличие от остальных монстров " + "он ищет свою жертву по её теплу.") + +S("Rangers take care of the magic mirrors in the Land of Mirrors. " + "They know that rogues like to break these mirrors... so " + "they will attack you!", + "Странники охраняют магические зеркала. Они знают, что эти " + "разбойники хотят разбить их зеркала и тут же нападают на Вас!") + +S("A nasty creature native to the Living Caves. They don't like you " + "for some reason.", + "Противное существо из Живых пещер. По каким-то причинам не любит людей.") + +S("A tribe of men native to the Desert. They have even tamed the huge Sandworms, who won't attack them.", + "Племя людей, живущих в пустыне. Они приручили песчаных червей, и те их не трогают.") + +S("This giant ape thinks that you are an enemy.", "Эта огромная обезьяна считает Вас своим врагом.") + +S("A magical being which copies your movements.", "Это магическое создание копирует Ваши движения.") + +S("A magical being which copies your movements. " + "You feel that it would be much more useful in an Euclidean space.", + "Это магическое создание повторяет Ваши движения. Вы понимаете, что в евклидовом мире это куда полезнее.") + +S("You can summon these friendly constructs with a magical process.", + "Магия позволяет призывать этих дружелюбных созданий.") + +S("A majestic bird, who is able to fly very fast.", + "Величественная птица, летающая очень быстро.") + +S("A monster who is able to live inside the living cave wall.", + "Этот монстр может жить внутри стен пещеры.") + +S("A typical Graveyard monster.", "Типичный для Кладбища монстр.") + +S("A typical monster from the Graveyard, who moves through walls.\n\n" + "There are also wandering Ghosts. They will appear " + "if you do not explore any new places for a long time (about 100 turns). " + "They can appear anywhere in the game.", + "Типичный для Кладбища монстр, умеющий проходить сквозь стены.\n\n" + "Также существуют блуждающие призраки. Они появляются, если Вы не исследуете новые места в течение большого времени (примерно 100 ходов). Они могут появиться в любом месте в игре" + ) + +S("Necromancers can raise ghosts and zombies from fresh graves.", + "Некромант может призывать призраков и зомби из свежих могил.") + +S("A creepy monster who follows you everywhere in the Graveyard.", + "Пугающий монстр, вечно преследующий Вас на Кладбище.") + +S("People worshipping Cthulhu. They are very dangerous.", + "Люди, поклоняющиеся Ктулху. Они довольно опасны.") + +S("People worshipping Cthulhu. This one is especially dangerous, " + "as he is armed with a weapon which launches fire from afar.", + "Люди, поклоняющиеся Ктулху. Этот особо опасен, так как " + "он может кинуть в Вас огонь.") + +S("This dangerous predator has killed many people, and has been sent to Cocytus.", + "Этот опасный хищник убил немало людей и был отправлен в Коцит.") + +S("This white dog is able to run all the time. It is the only creature " + "able to survive and breed in the Land of Eternal Motion.", + "Эта белая собака способна всё время бежать. Это единственное " + "существо, способное жить и размножаться в Земле вечного движения.") + +S("Demons of Hell do not drown when they fall into the lake in Cocytus. " + "They turn into demonic sharks, enveloped in a cloud of steam.", + "Демоны из Ада не тонут в озёрах Коцита. Они превращаются в " + "демонических акул, окутанных облаками пара.") + +S("These fairies would rather burn the forest, than let you get some Fern Flowers. " + "The forest is infinite, after all...\n\n" + "Fire Fairies transform into fires when they die.", + "Эти феи скорее сожгут лес, чем позволят Вам собрать цветок папоротника. " + "В конце концов, лес бесконечный...\n\n" + "Они превращаются в огонь, когда умирают.") + +S("These warriors of the Forest wield exotic weapons called hedgehog blades. " + "These blades protect them from a frontal attack, but they still can be 'stabbed' " + "easily by moving from one place next to them to another.", + "Эти лесные воители вооружены экзотическим оружием, называемым ежиным клинком. " + "Клинки защищают их от прямых атак, но они могут быть 'заколоты', " + "достаточно перейти с одной клетки рядом с нм на другую.") + +S("This being radiates an aura of wisdom. " + "It is made of a beautiful crystal, you would love to take it home. " + "But how is it going to defend itself? Better not to think of it, " + "thinking causes your brain to go hot...\n\n" + "Crystal Sages melt at -30 °C, and they can rise the temperature around you from afar.", + "Они излучают ауру мудрости. Они сделаны из красивых кристаллов, и Вы хотели бы " + "забрать их домой. Но как он собирается защищать себя? Лучше не думайте об этом, " + "мышление нагревает Ваш мозг...\n\n" + "Кристальные мудрецы тают при -30 °C, и они могут повысить температуру вокруг Вас издалека.") + +S("Cold white gems, found in the Icy Land.", "Холодные белые камни, найденные в Ледяной земле.") + +S("An expensive metal from the Living Caves. For some reason " + "gold prevents the living walls from growing close to it.", + "Драгоценный металл из Живых пещер. Он препятствует росту живых стен в клетку с ним.") + +S("A rare and expensive substance found in the Desert. " + "It is believed to extend life and raise special psychic powers.", + "Редкое и дорогое вещество из Пустыни. Говорят, продлевает срок жизни и даёт сверхспособности.") + +S("A beautiful gem from the Jungle.", "Прекрасный камень из Джунглей.") + +S( + "A wonderful beverage, apparently obtained by mixing red and blue slime. You definitely feel more " + "healthy after drinking it, but you still fell that one hit of a monster is enough to kill you.", + "Чудесный напиток, полученный из синей и красной слизи. Вы чувствуете себя лучше, выпив его, " + "но одного удара Вам всё ещё хватит, чтобы погибнуть.") + +S("A piece of a magic mirror, or a mirage cloud, that can be used for magical purposes. Only mirrors and clouds " + "in the Land of Mirrors leave these.", + "Часть магического зеркала или облака миражей. Может быть использовано в магических целях. " + "Может быть получено только в Зеркальной земле.") + +S("These sinister totems contain valuable gems.", + "Этот зловещий тотем содержит ценные камни.") + +S("These star-shaped flowers native to Hell are a valuable alchemical component.", + "Эти звездовидные цветы их Ада - важный алхимический компонент.") + +S("This statue is made of materials which cannot be found in your world.", + "Эти статуи сделаны из материала, который не найдёшь в Вашем мире.") + +S("One of few things that does not cause the floor in the Land of Eternal Motion to collapse. Obviously they are quite valuable.", + "Единственная вещь, которую выдерживает пол в Земле вечного движения. " + "Очевидно, довольно ценно.") + +S("Cold blue gems, found in the Cocytus.", "Холодные голубые камни, найденные в Коците.") + +S("These bright yellow gems can be found only by those who have mastered the Crossroads.", + "Эти ярко-жёлтые камни может найти лишь тот, кто стал мастером Перекрёстка.") + +S("That's all you need to unlock the Orb of Yendor! Well... as long as you are able to return to the Orb that this key unlocks...\n\n" + "Each key unlocks only the Orb of Yendor which led you to it.", + "Это всё, что Вам нужно, чтобы открыть Сферу Йендора! Ну, если Вы сможете к ней вернуться...\n" + "Каждый ключ открывает лишь ту сферу, которая на него указывает.") + +S("These orbs can be found in the Graveyard. You think that they were once powerful magical orbs, but by now, their " + "power is long gone. No way to use them, you could as well simply drop them...\n\n", + "Эту сферу можно найти на Кладбище. Когда-то она обладала могущественной магией, но теперь её сила иссякла. " + "Нет способа её использовать. Разве что просто бросить её...\n\n") + +S( + "This wonderful Orb can only be collected by those who have truly mastered this hyperbolic universe, " + "as you need the right key to unlock it. Luckily, your psychic abilities will let you know " + "where the key is after you touch the Orb.", + "Эта прекрасная сфера может быть собрана лишь тем, кто по настоящему освоил гиперболическую вселенную, " + "но Вам нужно найти ключ от неё. К счастью, Вы узнаете, где он лежит, как только дотронетесь до сферы.") + +S( + "This orb can be used to invoke the lightning spell, which causes lightning bolts to shoot from you in all directions.", + "Эта сфера может использоваться для заклинания Молнии, которое бьёт молниями во всех направлениях.") + +S("This orb can be used to invoke a flash spell, which destroys almost everything in radius of 2.", + "Эта сфера вызывает заклинание вспышки, уничтожающее почти всё в радиусе 2.") + +S("This orb can be used to invoke a wall of ice. It also protects you from fires.", + "Эта сфера создаёт за Вами стену льда. Также защищает Вас от огня.") + +S("This orb can be used to move faster for some time.", + "Эта сфера ускорит Вас на некоторое время.") + +S("This orb can be used to summon friendly golems. It is used instantly when you pick it up.", + "Эта сфера призывает дружественных големов. Она срабатывает, как только Вы её поднимаете.") + +S("This orb can protect you from damage.", "Эта сфера защитит Вас от всех атак.") + +S("This orb lets you instantly move to another location on the map. Just click a location which " + "is not next to you to teleport there. ", + "Эта сфера позволяет перемещаться в произвольное место. Просто кликните по не соседней с Вами клетке, " + "чтобы телепортироваться туда.") + +S("This orb lets you instantly move to a safe faraway location. Knowing the nature of this strange world, you doubt " + "that you will ever find the way back...\n\n" + "Your game will be saved if you quit the game while the Orb of Safety is still powered.\n\n" + "Technical note: as it is virtually impossible to return, this Orb recycles memory used for the world so far (even if you do not use it to save the game). ", + "Эта сфера перемещает Вас в далёкое безопасное место, откуда Вы не вернётесь назад...\n\n" + "Пока сфера активна, при выходе из игры Ваша игра будет сохранена.\n\n" + "Технически, старый мир просто удаляется. ") + +S("This orb allows attacking Hedgehog Warriors directly, as well as stabbing other monsters.\n", + "Эта сфера позволит прямо атаковать Ежей-Воинов и закалывать тех врагов, которых Вы могли убить обычным путём.\n") + +S("This flower brings fortune to the person who finds it.\n", + "Этот цветок приносит удачу тому, кто найдёт его.\n") + +S("Ice Walls melt after some time has passed.", "Ледяные стены со временем могут таять.") + +S("A natural terrain feature of the Desert.", "Натуральный ландшафт пустыни.") + +S("You can go inside the Magic Mirror, and produce some mirror images to help you.", + "Вы можете пройти в Магическое зеркало и создать отражения, которые будут Вам помогать.") + +S( + "Tiny droplets of magical water. You see images of yourself inside them. " + "Go inside the cloud, to make these images help you.", + "Крошечные капли магической жидкости. Вы видите в них свои отражения. " + "Войдите в облако, чтобы создать двойников, помогающих Вам.") + +S("A device that attracts sandworms and other enemies. You need to activate it.", + "Этот аппарат привлекает песчаных червей и других врагов. Вам нужно активировать его.") + +S("A heap of wood that can be used to start a fire. Everything is already here, you just need to touch it to fire it.", + "Куча брёвен. Всё готово для костра, Вам нужно лишь поджечь его.") + +S("An ancient grave.", "Старая могила.") + +S("A fresh grave. Necromancers like those.", "Свежая могила. Некроманты их любят.") + +S("A piece of architecture typical to R'Lyeh.", "Типичная архитектура Р'Льеха.") + +S("An impassable lake in Cocytus.", "Непроходимое озеро в Коците.") + +S("You can walk on it... but beware.", "Вы можете пойти сюда, но будьте осторожны!") + +S("It was a floor... until something walked on it.", "Здесь был пол... пока кто-то не наступил не него.") + +S( + "This land is a quick gateway to other lands. It is very easy to find other lands " + "from the Crossroads. Which means that you find monsters from most other lands here!\n\n" + "As long as you have found enough treasure in their native lands, you can " + "find magical items in the Crossroads. Mirror Land brings mirrors and clouds, " + "and other land types bring magical orbs.\n\n" + "A special treasure, Hyperstone, can be found on the Crossroads, but only " + "after you have found 10 of every other treasure.", + "Эта земля - кратчайший путь в любую другую. Здесь очень легко найти любую " + "другую землю, и здесь можно встретить монстров изо всех земель!\n\n" + "Как только Вы набираете достаточно сокровищ в некоторой земле, её магические " + "предметы становятся доступны здесь. В Зеркальной земле это зеркала и миражи, в остальных - сферы.\n\n" + "Свой сокровище, Гиперкамень, появится лишь после того, как Вы соберёте по 10 сокровищ каждого типа.") + +S("A hot land, full of sand dunes, mysterious Spice, and huge and dangerous sand worms.", + "Жаркая земля, полная песчаных дюн, загадочных специй и огромных опасных червей.") + +S( + "A very cold land, full of ice walls. Your mere presence will cause these ice walls to " + "melt, even if you don't want it.", + "Очень холодная земля, полная ледяных стен. Они будут таять от Вашего присутствия, даже если Вы этого не хотите.") + +S("A land filled with huge ivy plants and dangerous animals.", + "Земля, полная огромными плющами и опасными животными.") + +S("A strange land which contains mirrors and mirages, protected by Mirror Rangers.", + "Странная земля с зеркалами и миражами, защищёнными Странниками.") + +S("All the monsters you kill are carried to this strange land, and buried. " + "Careless Rogues are also carried here...", + "Все убитые Вами монстры похоронены здесь. И неосторожные охотники за сокровищами тоже...") + +S("An ancient sunken city which can be reached only when the stars are right.\n\n" + "You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Этот древний затопленный город можно найти лишь тогда, когда на него укажут звёзды.\n\n" + "Вы сможете найти храмы Ктулху, как только соберёте 5 статуй Ктулху.") + +S("A land filled with demons and molten sulphur. Abandon all hope ye who enter here!", + "Земля, полная демонов и расплавленной серы. Оставь надежду всяк сюда входящий!") + +S("This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.", + "Замёрзшее озеро - адский вариант Ледяной земли. Но сейчас тепло плавит пол, а не стены.") + +S("A land where you cannot stop, because every piece of floor is extremely unstable. Only monsters who " + "can run forever are able to survive there, and only phoenix feathers are so light that they do not disturb " + "the floor.\n", + "Земля, в которой нельзя остановиться, потому что пол крайне неустойчив. Лишь монстры, способные всегда бежать, " + "могут здесь выжить, и лишь перья феникса столь легки, что не тревожат землю.\n") + +S("Affects looks and grammar", "Влияет на внешний вид и грамматику") + +S("first joystick: movement threshold", "джойстик 1: порог движения") +S("first joystick: execute movement threshold", "джойстик 1: порог выполнения движения") +S("second joystick: pan threshold", "джойстик 2: порог панорамы") +S("second joystick: panning speed", "джойстик 2: скорость панорамы") +S("%The1 is frozen!", "%1 замерзает!") +S("%The1 burns!", "%1 горит!") +S("message flash time", "время показа сообщений") + +S("skin color", "цвет кожи") +S("weapon color", "цвет оружия") +S("hair color", "цвет волос") +S("dress color", "цвет одежды") +S("Shift=random, Ctrl=mix", "Shift=случайный, Ctrl=смешать") + +S("Euclidean mode", "режим евклидовой плоскости") +S("Return to the hyperbolic world", "вернуться на гиперболоид") +S("Choose from the lands visited this game.", "Выберите одну из уже посещённых земель.") +S("Scores and achievements are not", "Очки и достижения не"); +S("saved in the Euclidean mode!", "сохраняются в евклидовом режиме!"); + +// Android buttons (some are not translated because there are no good short words in Polish) +S("MOVE", "ХОД") +S("BACK", "BACK") +S("DRAG", "DRAG") +S("INFO", "ИНФО") +S("MENU", "МЕНЮ") +S("QUEST", "МИССИЯ") +S("HELP", "ПОМОШЬ") +S("NEW", "NEW") +S("PLAY", "ИГРА") +S("SHARE", "SHARE") +S("HyperRogue for Android", "HyperRogue для Android") +S("Date: %1 time: %2 s ", "Дата: %1 время: %2 s ") +S("distance: %1\n", "расстояние: %1\n") +S("Cheats: ", "Читы: ") +S("Score: ", "Очки: ") +S("Kills: ", "Убийства: ") +S("Retrieving scores from Google Leaderboards...", "Получение результатов из таблиц Google...") +S("Scores retrieved.", "Результаты получены.") + +S("Your total treasure has been recorded in the Google Leaderboards.", "Ваш результат записан в рейтинг Google.") +S("You have improved your total high score on Google. Congratulations!", "Вы поставили рекорд по общему счёту в таблицах Google. Поздравляем!") +S("You have improved your '%1' high score on Google!", "Вы повысили свой результат '%1' в таблицах Google") +S("This has been recorded in the Google Leaderboards.", "Это было записано в рейтинг Google.") + +// this text changed a bit: + +S("Ever wondered how some boardgame would look on the hyperbolic plane? " + "I wondered about Go, so I have created this feature. Now you can try yourself!\n" + "Enter = pick up an item (and score), space = clear an item\n" + "Other keys place orbs and terrain features of various kinds\n" + "In the periodic editor, press 0-4 to switch walls in different ways\n", + "Вы когда-нибудь думали о том, как выглядит настольная игра на гиперболической плоскости? " + "Я думал про Го и создал этот режим. Теперь и Вы можете попробовать!\n" + "Enter = поднять предмет, space = удалить предмет\n" + "Остальные клавиши добавляют разные предметы или элементы ландшафта.\n" + "В периодическом редакторе клавиши 0-4 меняют местоположение стен разными способами.\n") + +S("Periodic Editor", "Периодический редактор") +// also translate this line: +// "In the periodic editor, press 0-4 to switch walls in different ways\n", + +S("Collect 60 $$$ to access even more lands", "Соберите 60 $$$, чтобы открыть новые земли") + +// Emerald Mine + +N("Emerald Mine", GEN_F, "Изумрудная шахта", "Изумрудные шахты", "Изумрудную шахту", "в Изумрудной шахте") +N("Pikeman", GEN_M, "Копейщик", "Копейщики", "Копейщика", "Копейщиком") +N("Flail Guard", GEN_M, "Воин с цепом", "Воины с цепом", "Воина с цепом", "Воином с цепом") +N("Miner", GEN_M, "Шахтёр", "Шахтёры", "Шахтёра", "Шахтёром") +N("Emerald", GEN_O, "Изумруд", "Изумруды", "Изумруд", "Изумрудом") + +Orb("the Mind", "Разума") + +S( + "Evil people are mining for emeralds in this living cave. " + "It does not grow naturally, but it is dug out in a regular " + "pattern, which is optimal according to the evil engineers.", + "Злые люди искали изумруды в Живой пещере. " + "Она не растёт сама, но выкопана периодически " + "оптимально для нужд злых инженеров. ") + +S( + "Miners have special tools for dealing with the Living Cave. " + "When they die, these tools activate, destroying the living cave " + "around them.", + "Шахтёры имеют специальные инструменты для копания Живой пещеры. " + "При гибели они автоматически используются, уничтожая пещеру вокруг них.") + +S( + "When Pikemen move, they attack all cells which are now adjacent to them. " + "Luckily, they can be killed in the same way.\n\n" + "They never move if this would attack their friends.", + "Когда Копейщик ходит, он атакует все клетки рядом с ним. К счастью, и его можно убить подобным образом.\n\n" + "Копейщик никогда не будет атаковать дружественной ему существо.") + +S( + "This guard of the Emerald Mine is wielding a huge flail. " + "You cannot attack him directly, as the flail would still hit you then. " + "Luckily, you have learned a trick: if you step away from him, " + "he will hit himself with the flail!", + + "Этот страж изумрудных шахт вооружён огромным цепом. " + "Вы не можете атаковать его обычным путём, потому что тогда цеп убьёт Вас. " + "К счастью, Вы знаете трюк: достаточно отойти от него, когда он замахивается, " + "и он убьёт сам себя!") + +S("A precious green gem from the Emerald Mines.", "Ценный зелёный камень из изумрудных шахт.") + +S("%The1 pierces %the2!", "%1 проколол%E1 %a2!") + +S("Make him hit himself by walking away from him.", + "Заставьте его ударить самого себя, просто подойдя к нему.") + +S("This orb allows you to instantly kill a non-adjacent enemy by clicking it. " + "Each use drains 30 charges.", + "Эта сфера позволит Вам убить любого врага, не стоящего рядом с Вами, просто кликнув по нему. " + "Это действие тратит 30 зарядов.") + +S("%The1 is immune to mental blasts!", "%1 защищён%E1 от психических атак!") +S("You kill %the1 with a mental blast!", "Вы убили %a1 психическим взрывом!") + +// Vineyard + +N("Vineyard", GEN_O, "Виноградник", "Виноградники", "Виноградник", "в Винограднике") +N("Vine Beast", GEN_M, "Винный зверь", "Винные звери", "Винного зверя", "Винным зверем") +N("Vine Spirit", GEN_M, "Винный дух", "Винные духи", "Винного духа", "Винным духом") +N("vine", GEN_F, "лоза", "лозы", "лозы", "лозой") +N("partial fire", GEN_O, "частичный огонь", "частичные огни", "частичный огонь", "частичным огнём") +N("Wine", GEN_N, "Вино", "Вина", "Вино", "Вином") + +S( "This cell is partially on fire.", "Эта клетка частично в огне.") + +S( + "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n" + "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.", + "Виноградник полон виноградными лозами. Они образуют очень плотный узор из прямых...\n\n" + "Винные звери и духи превращают траву в вино и наоборот.") + +S("A vine is growing here... but only on a half of the cell. How is that even possible?!" + "Most monsters cannot move from this cell to the cell containing the other half. " + "Vine spirits can move only to the adjacent cells which are also adjacent to the " + "other half.", + "Здесь растёт лоза... но только на половине клетки. Как это возможно?! " + "Большинство монстров не могут перейти с этой клетки на соседнюю с ней по стороне, содержащей лозу; " + "винный дух, напротив, на может перейти с этой клетки на лозу, соседнюю с ней по свободной половине.") + +S( + "A beast made of vines!\n\n" + "Vine Beasts turn into vines when they die.", + "Зверь, свитый из виноградных лоз!\n\n" + "Винный зверь превращается в лозу при гибели.") + +S( "A spirit living in the vines!\n\n" + "Vine Spirits destroy the vines when they die.", + "Дух, живущий в лозе\n\n" + "Винный дух уничтожает лозу при гибели.") + +S("Wine grown under hyperbolic sun would be extremely prized in your home location.", + "Вино, созревшее под гиперболическим солнцем, очень ценится на Вашей родине.") + +S("This orb allows one to pass through all kinds of walls and chasms.", + "Эта сфера позволяет ходить через все стены и пропасти.") + +S("You cannot attack through the Vine!", + "Вы не можете атаковать сквозь лозу!") + +Orb("Aether", "Эфира") + +// Dead Caves + +N("Dead Cave", GEN_F, "Мёртвая пещера", "Мёртвые пещеры", "Мёртвую пещеру", "в Мёртвой пещере") +N("Dark Troll", GEN_M, "Тёмный тролль", "Тёмные тролли", "Тёмного тролля", "Тёмным троллем") +N("Earth Elemental", GEN_M, "Земной элементаль", "Земные элементали", "Земного элементаля", "Земным элементалем") +N("dead wall", GEN_F, "мёртвая стена", "мёртвые стены", "мёртвую стену", "мёртвой стеной") +N("dead floor", GEN_O, "мёртвый пол", "мёртвые полы", "мёртвый пол", "мёртвым полом") +N("rubble", GEN_O, "щебень", "щебни", "щебень", "щебнем") +N("Silver", GEN_N, "Серебро", "Серебро", "Серебро", "Серебром") + +S("A precious metal from the Dead Caves.", "Драгоценный металл из Мёртвых пещер.") + +S( "A Troll without the power of Life.", "Тролль без жизненной силы.") + +S( + "A rare unliving construct from the Dead Caves. " + "It instantly destroys cave walls next to its path, and also leaves " + "an impassable wall behind it. You suppose that this impassable wall helps it to " + "escape from some threats. You hope you won't meet these threats...", + + "Редкое неживое создание из Мёртвых пещер. " + "Мгновенно разрушает стены на своём пути и оставляет стены за собой.") + +S("%The1 punches %the2!", "%1 ударил%E1 %a2!") +S("%The1 is destroyed by the forces of Life!", "Сила Жизни уничтожила %a1!") +S( "Somehow, this cave has not received the spark of Life yet.", + "Так или иначе, в эту пещеру ещё не пришла жизнь.") + +// Hive +N("Hive", GEN_O, "Улей", "Ульи", "Улей", "в Улье") +N("Red Hyperbug", GEN_M, "Красный гипержук", "Красные гипержуки", "Красного гипержука", "Красным гипержуком") +N("Green Hyperbug", GEN_M, "Зелёный гипержук", "Зелёные гипержуки", "Зелёного гипержука", "Зелёным гипержуком") +N("Blue Hyperbug", GEN_M, "Синий гипержук", "Синие гипержуки", "Синего гипержука", "Синим гипержуком") +N("Royal Jelly", GEN_N, "маточное молочко", "маточное молочко", "маточное молочко", "маточным молочком") +N("weird rock", GEN_O, "странный камень", "странные камни", "странный камень", "странным камнем") + +Orb("Invisibility", "Невидимости") + +S("A weirdly colored rock. Hyperentomologists claim that the " + "Hyperbug armies use these rocks to navigate back home after a victorious battle.", + "Странно окрашенный камень. Гиперэнтомологи считают, что армии " + "гипержуков используют их, чтобы вернуться после победоносной битвы домой.") + +S("%The1 fights with %the2!", "%1 атаковал%E1 %a2!") + +S("The Hive is filled with Hyperbugs. They are huge insects which look a bit like " + "ants, a bit like bees, and a bit like roaches. " + "They live in circular nests, and an army of Hyperbugs will attack any intruder, " + "including you and enemy Hyperbugs. Will you manage to get to the " + "heart of such a nest, and get the precious Royal Jelly?", + "Улей населён гипержуками. Эти огромные насекомые выглядят немного как муравьи, " + "немного как пчёлы и немного как тараканы. Они живут в круглых гнёздах, " + "и их армия готова напасть на любого нарушителя, включая Вас и жуков другого цвета. " + "Хотите ли Вы добраться до центра такого гнезда и забрать ценное маточное молочко?") + +S("This is what Hyperbug Queens eat. Very tasty and healthy.", + "Это - еда королевы гипержуков. Очень вкусно и полезно.") + +S("When you have this Orb, most monsters won't see you, unless " + "you are standing still, attacking, or picking up items.", + "Пока у Вас есть эта сфера, большинство монстров не видят Вас, " + "если Вы не стоите рядом, не атакуете и не поднимаете предметы.") + +Orb("Earth", "Земли") + +S("This orb lets you go through living walls. It also has powers in some of the other lands.", + "Эта сфера позволяет проходить сквозь живые стены. Она имеет силу и в некоторых других землях.") + +// Land of Power + +N("Land of Power", GEN_F, "Земля силы", "Земли силы", "Землю силы", "в Земле силы") +N("Witch Apprentice", GEN_F, "Ведьма-ученица", "Ведьмы-ученицы", "Ведьму-ученицу", "Ведьмой-ученицей") +N("Speed Witch", GEN_F, "Ведьма скорости", "Ведьмы скорости", "Ведьму скорости", "Ведьмой скорости") +N("Flash Witch", GEN_F, "Ведьма вспышки", "Ведьмы вспышки", "Ведьму вспышки", "Ведьмой вспышки") +N("Fire Witch", GEN_F, "Ведьма огня", "Ведьмы огня", "Ведьму огня", "Ведьмой огня") +N("Aether Witch", GEN_F, "Ведьма эфира", "Ведьмы эфира", "Ведьму эфира", "Ведьмой эфира") +N("Winter Witch", GEN_F, "Ведьма зимы", "Ведьмы зимы", "Ведьму зимы", "Ведьмой зимы") +N("Evil Golem", GEN_M, "Злой голем", "Злые големы", "Злого голема", "Злым големом") +N("Powerstone", GEN_O, "Камень силы", "Камни силы", "Камень силы", "Камнем силы") +N("crystal cabinet", GEN_O, "кристальный кабинет", "кристальные кабинеты", "кристальный кабинет", "кристальным кабинетом") + +S("When you have this Orb, you will leave a trail of fire behind you.", + "Пока у Вас есть эта сфера, Вы оставляете огненный след за собой.") + +S( + "A Witch without any special powers. But watch out! She will " + "pick up any basic Orbs on her path, and use their powers.", + "Ведьма без особых сил. Но будьте осторожны! Она может поднять " + "сферу на своём пути и забрать её силу.") + +S( "A Witch with a Speed spell. She moves twice as fast as you. Unless you " + "have an Orb of Speed too, of course!", + "Ведьма с заклинанием скорость. Она движется в 2 раза быстрее Вас. " + "Если у Вас нет того же заклинания, конечно!") + +S( "A Witch with a Fire spell. She will leave a trail of fire behind her.", + "Ведьма с заклинанием огня. Оставляет огненный след за собой.") + +S( "A Witch with a Winter spell. She is able to move through fire.", + "Ведьма с заклинанием зимы. Может проходить сквозь огонь.") + +S( "A Witch with an Aether spell. She is able to move through fire and walls.", + "Ведьма с заклинанием эфира. Может проходить сквозь огонь и стены.") + +S( "Somebody has summoned these evil constructs with a magical process.", + "Враждебная конструкция, созданная в результате магического процесса.") + +S( "The Land of Power is filled with everburning fire, magical Orbs, and guarded by " + "witches and golems. There are basic orbs lying everywhere, and more prized ones " + "are kept in crystal cabinets.\n\n" + "Witches are allowed to use all the powers of the " + "basic orbs against intruders. These powers never expire, but a Witch " + "can use only one power at a time (not counting Orbs of Life).\n\n" + "Witches and Golems don't pursue you into other Lands. Also, most Orb powers" + "are drained when you leave the Land of Power.", + "Земля силы полна вечно горящими огнями и магическими сферами и защищена " + "ведьмами и големами. Все обычные сферы есть здесь, " + "и наиболее ценные из них защищены кристальными кабинетами.\n\n" + "Ведьмы способны использовать силы сфер против нарушителей. " + "Эти силы действуют бесконечно, но каждая ведьма может использовать лишь " + "Одну (не считая сферы жизни).\n\n" + "Ведьмы и големы не покидают эту землю. Когда вы уходите из неё, силы некоторых " + "Ваших сфер покидают Вас.") + +S( + "Witches use these crystal cabinets to protect Powerstones, as well as the more " + "expensive Orbs. They are partially protected from thieves: they are too strong " + "to be smashed by conventional attacks, and if you try to steal the item " + "using an Orb of Aether, your Aether power will be completely drained.", + "Ведьмы используют эти кристальные кабинеты для защиты Камней силы, как и самые " + "ценные сферы. Они частично защищают их от воров: они достаточно прочны, чтобы " + "выдерживать прямые атаки, и если Вы попробуете использовать сферу Эфира для " + "проникновения в него, то сила сферы сразу иссякнет.") + +S( + "A Stone from the Land of Power. You are not sure what it is exactly, but " + "as the Powerstones are kept in crystal cabinets, they are surely valuable.", + "Камень из Земли силы. Вы точно не знаете, что это такое, но раз они спрятаны " + "в кристальных кабинетах, они довольно ценны.") + +Orb("Fire", "Огня") + +// achievements: + +// x "Head Witch", "Have 10 Orbs active at the same time." +// "Enemy Number One", "Have an army of 1000 hyperbugs pursue you." +// x "Lifebringer", "Brought Life into the Dead Caves." +// "Wall Gardener", "Make a living wall grow outside of a cavernous region." +// x "Master Swordsman", "Defeat a Hedgehog Warrior, a Pikeman, and a Flail Guard at the same time." +// x "Master of Melee", "Defeat five monsters in melee at the same time." + +// for collection achievements: +// provide the required cases for descriptions: +// Spice, Royal Jelly, Silver, Powerstone, and Wine +// achievement names: +// Master of the Hive, Master of Power, Master of Vineyard, Master of Dead Caves, Master of the Mine +// "Hyperbug", "Hyperbug Warrior", "Hyperbug Queen", + +// for the store description: + +// (currently, five more lands are included!) + +// lines forgotten previously + +S("Your Aether power has expired! RUN!", "Ваша эфирная сила иссякает! БЕГИТЕ!") + +S("%The1 tricks %the2.", "%1 победил%E1 %a2.") +S("You trick %the1.", "Вы победили %a1.") + +S( "A Witch with a Flash spell. Very dangerous!\n\nLuckily, she never uses the spell if it " + "would kill her friends. She could destroy an Evil Golem, though.", + "Ведьма с заклинанием вспышки. Очень опасна!\n\nК счастью, она никогда не использует " + "заклинание, ели оно убьёт других ведьм. Но големов она может и уничтожить.") + +S("Your Aether powers are drained by %the1!", "Твоя эфирная сила была уменьшена %abl1!") +S("As you leave, your powers are drained!", "Покидая землю силы, Вы теряете магию сфер!") +S("%The1 picks up %the2!", "%1 поднял%E1 %a2!") // currently only Witches, so only female form + +S("You can right click any element to get more information about it.\n\n", + "Кликните правой кнопкой мыши, чтобы узнать больше.\n\n") + +S("TRANSLATIONWARNING", "") + +S("The Hyperbugs are fighting!", "Гипержуки сражаются!") + +S("","") N("",GEN_N,"","","","") + +S("Cheat-changed the display.", "Отображение использованных читов.") +S("Dead floor, with some rubble.", "Мёртвая земля с щебнем.") + +// Camelot + +N("Camelot", GEN_O, "Камелот", "Камелот", "Камелот", "в Камелоте") +N("wall of Camelot", GEN_F, "стена Камелота", "стены Камелота", "стену Камелота", "стеной Камелота") +N("moat of Camelot", GEN_O, "ров Камелота", "рвы Камелота", "ров Камелота", "рвом Камелота") +N("Round Table", GEN_O, "Круглый Стол", "Круглые Столы", "Круглый Стол", "Круглому Столу") +N("Knight", GEN_M, "Рыцарь", "Рыцари", "Рыцаря", "Рыцарем") +N("Holy Grail", GEN_O, "Святой Грааль", "Святые Граали", "Святой Грааль", "Святым Граалем") + +S( + "The Knights of the Round Table are the greatest warriors of these lands. " + "They are not very inventive with names though, as they call each of their " + "castles Camelot. " + "You are probably worth of joining them, but they will surely give you " + "some quest to prove yourself...\n\n" + "Each castle contains a single treasure, the Holy Grail, in the center. " + "The radius of the Round Table is usually 28, but after you find a Holy Grail " + "successfully, each new castle (and each Round Table) you find will be bigger.", + + "Рыцари Круглого стола - величайшие воины этой земли. " + "Они не очень изобретательны и называют каждый свой замок Камелот. " + "Возможно, Вам стоит встретиться с ними, и они дадут Вам задание.\n\n" + "Каждый замок содержит одно сокровище (Святой Грааль) в центре. Обычно радиус " + "круглого стола равен 28, но с каждым новым Граалем радиус становится всё больше.") + +S("It would be impolite to land on the table!", + "Было бы невежливо приземляться на стол!") +S("You jump over the table!", "Вы запрыгнули на стол!") +S("That was not a challenge. Find a larger castle!", + "Это было несложно. Найдите больший замок!") +S("The Knights congratulate you on your success!", + "Рыцари поздравляют Вас с успехом!") +S("The Knights laugh at your failure!", + "Рыцари смеются над Вашей неудачей!") +S("The Knights stare at you!", "Рыцари смотрят на Вас!") +S("Come on, this is too easy... find a bigger castle!", + "Ну давай, это слишком просто... Найди больший замок!") +S("The Knights wish you luck!", "Рыцари желают Вам удачи!") + +S("Congratulations! You have found the Holy Grail!", + "Поздравляем! Вы нашли святой Грааль!") + +S("\"I would like to congratulate you again!\"", "\"Я хотел бы ещё раз Вас поздравить!\"") +S("\"Find the Holy Grail to become one of us!\"", "\"Найди Святой Грааль, и станешь одним из нас!\"") +S("\"The Holy Grail is in the center of the Round Table.\"", "\"Святой Грааль в центре круглого стола.\"") +S("\"I enjoy watching the hyperbug battles.\"", "\"Мне нравится наблюдать за боями гипержуков.\"") +S("\"Have you visited a temple in R'Lyeh?\"", "\"Вы уже были в храме в Р'Льехе?\"") +S("\"Nice castle, eh?\"", "\"Хороший замок, да?\"") + +// Temple + +N("Temple of Cthulhu", GEN_O, "Храм Ктулху", "Храмы Ктулху", "Храм Ктулху", "в Храме Ктулху") +N("big statue of Cthulhu", GEN_O, "памятник Ктулху", "памятники Ктулху", "памятник Ктулху", "памятником Ктулху") +N("Grimoire", GEN_O, "Гримуар", "Гримуары", "Гримуар", "Гримуаром") +N("Cult Leader", GEN_M, "Лидер культа", "Лидеры культа", "Лидера культа", "Лидером культа") + +S("The temple of Cthulhu consists of many concentric circles of columns. " + "You will surely encounter many Cultists there, who believe that a pilgrimage " + "to the inner circles will bring them closer to Cthulhu himself, and Grimoires " + "which surely contain many interesting secrets.\n\n" + "The circles in the temple of Cthulhu are actually horocycles. They are " + "infinite, and there is an infinite number of them.", + + "Храм Ктулху содержит много концентрических кругов колонн. " + "Здесь Вы встретите культистов, верящих, что путешествие во внутренние круги " + "храма приблизит их ко Ктулху, и найдёте Гримуары, содержащие весьма интересные секреты.\n\n" + "Круги в храме на самом деле орициклы. Они бесконечны, и их число бесконечно." + ) + +S("The Grimoires contain many secrets of the Great Old Ones. " + "Each new inner circle in the Temple of Cthulhu contains new Grimoires, with new secrets. " + "You hope to read them when you return home, and to learn many things. " + "The knowledge is valuable to you, but it is rather pointless to try to get " + "several copies of the same Grimoire...", + "Гримуары содержат много секретов Великих предков Каждый новый круг Храма Ктулху содержит " + "новые тома с новыми секретами. Вы можете принести их домой, прочитать и узнать много вещей." + "Знание ценно для Вас, но Вам не нужны копии одного Гримуара... " + ) + +S("These statues of Cthulhu are too large to carry, and they don't look too " + "valuable anyway. Most monsters will never go through them... they probably have " + "their reasons. But you can go! When you move into the cell containing " + "a statue, you push the statue to the cell you left.\n", + + "Эти статуи Ктулху слишком велики, чтобы их забрать, да и не выглядят особо ценными. " + "Большинство монстров не может ходить через них, у них есть на то свои причины. " + "Но Вы можете! Когда Вы ходите на клетку с памятником, " + "он сдвигается на клетку, которую Вы покинули." + ) + +S("These Cultists can push the statues, just like you.", + "Эти культисты могут двигать статуи,как и Вы.") + +S("You already have this Grimoire! Seek new tomes in the inner circles.", + "У Вас уже есть этот Гримуар! Ищите новые тома в более глубоких кругах.") + +S("You push %the1 behind you!", "Вы передвинули %a1 за себя.") + +// More texts + +S("Your total kills", "Всего убийств") + +S( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count.", + + "В большинстве земель чем больше Вы убиваете местных жителей, тем больше сокровищ " + "создаётся. Кроме того, Вам нужно убить 100 врагов, чтобы попасть на Кладбище и в Улей.\n\n" + "Дружественные существа и части монстров (например, части плюща) при этом на считаются.") + +S("There must be some temples of Cthulhu in R'Lyeh...", + "В Р'Льехе должны быть храмы Ктулху...") + +S("You overheard Hedgehog Warriors talking about emeralds...", + "Вы слышите ежей-воинов, говорящих об изумрудах...") + +S("You overhear miners talking about a castle...", + "Вы слышите шахтёров, говорящих о замке...") + +S("A castle in the Crossroads...", "О замке на перекрёстке...") + +/* +S("You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Вы можете найти храмы Ктулху в Р'Льехе, как только найдёте 5 статуй Ктулху.") +*/ + +S("You have to escape first!", "Вы должны бежать первым!"); +S("There is not enough space!", "Нет места!"); + +S("Customize character", "Настройка персонажа") +S("gender", "пол") + +S("Cannot teleport on a monster!", "Нельзя телепортироваться на монстра!") +S("Cannot teleport on an item!", "Нельзя телепортироваться на предмет!") +S("Cannot teleport here!", "Нельзя телепортироваться сюда!") +//S("You cannot teleport that far away!", "Вы не можететелепортироваться так далеко!") +S("You cannot target that far away!", "Nie możesz celować tak daleko!") +S("You cannot target that close!", "Nie możesz celować tak blisko!") +S("Cannot cast illusion on an item!", "Nie możesz rzucić iluzji na przedmiot!") +S("Cannot cast illusion here!", "Nie możesz rzucić ilzuji tutaj!") +S("Cannot cast illusion on a monster!", "Nie możesz rzucić ilzuji na potwora!") +S("Cannot throw fire there!", "Nie możesz tego podpalić!") + +Orb("the Dragon", "Дракона") + +S("This Orb allows you to throw fire, just like the Fire Cultists.\n\n" + "Each fire drains 5 charges. You are not allowed to throw fire into adjacent cells.", + "Эта сфера позволит Вам кидать огонь, прямо как огненные культисты.\n\n" + "Каждое использование тратит 5 зарядов. Вы не можете кинуть огонь на соседнюю клетку." + ) + +S("You throw fire!", "Вы бросили огонь!") + +Orb("Trickery", "Хитрости") + +N("Illusion", GEN_F, "Иллюзия", "Иллюзии", "Иллюзию", "Иллюзией") + +S("Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.", + "Их будут атаковать почти все монстры, " + "так же как Вас, Тамперы и ваших союзников.") + +S("This Orb allows you to create illusions of yourself. Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.\n\n" + "Each illusion takes 5 charges to create, and one extra charge " + "per turn. You can also click your illusion to take it away, restoring 4 charges.\n\n" + "If you have both Orb of Teleport and Orb of Trickery, Illusion is cast " + "first -- you can then teleport on your Illusion to switch places with it.", + "Эта сфера позволяет Вам создавать иллюзии. Их будут атаковать почти все монстры, " + "так же как Вас, Тамперы и ваших союзников.\n\n" + "Каждая иллюзия требует 5 зарядов для создания и по одному в каждый ход. " + "Также Вы можете кликнуть на иллюзию, чтобы забрать её, потратив 3 заряда.\n\n" + "Если у Вас есть сферы Хитрости и Телепорта, Иллюзия работает первой -- Вы можете" + "потом телепортироваться на неё, чтобы поменяться с ней местами.") + // Иллюзии "Хитрости" +S("Illusions are targetted by most monsters, just like yourself, Thumpers, and your friends.", + "Их будут атаковать почти все монстры, " + "так же как Вас, Тамперы и ваших союзников.") + +S("You create an Illusion!", "Вы создали иллюзию!") +S("You take the Illusion away.", "Вы забрали иллюзию!") + +S("You cannot target that far away!", "Вы не можете выбрать цель так далеко!") +S("You cannot target that close!", "Вы не можете выбрать цель так близко!") +S("Cannot cast illusion on an item!", "Нельзя создать иллюзию на предмете!") +S("Cannot cast illusion here!", "Нельзя создать иллюзию здесь!") +S("Cannot cast illusion on a monster!", "Нельзя создать иллюзию на монстре!") +S("Cannot throw fire there!", "Вы не можете кинуть огонь сюда!") + +S("or ESC to see how it ended", "либо ESC, чтобы посмотреть, как всё закончилось") + +S("high contrast", "высокий контраст") + +S("draw the heptagons darker", "семиугольники темнее"); + +S("targetting ranged Orbs Shift+click only", + "выбирать цель сфер только через Shift+клик") + +S("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.", + "Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, и т. д..") + +S("also hold Alt during the game to toggle high contrast", + "также Alt во время игры переключает высокий контраст") + + +#undef Orb diff --git a/language-tr.cpp b/language-tr.cpp new file mode 100644 index 00000000..105802db --- /dev/null +++ b/language-tr.cpp @@ -0,0 +1,1366 @@ +// This translation file is encoded with UTF-8 + +// Nouns. + +#define Orb(X,Y) N("Orb of "X, GEN_F, Y" Küresi", Y" Küreleri", Y" Küresini", Y" Küresiyle") + + +// For each noun, provide the type of the noun, and all the grammatical forms +// required by HyperRogue. For example, in Polish each noun can be +// masculine living (GEN_M), masculine object (GEN_O), +// feminine (GEN_F), or neuter (GEN_N). The following forms are given: +// nominative (referred to as %1), nominative plural (%P1), accusative (%a1). +// Feel free to add more (or less) forms or types if needed. + +N("Yeti", GEN_M, "Yeti", "Yeti", "Yeti", "Yeti") +N("Icewolf", GEN_M, "Buzkurdu", "Buzkurtları", "Buzkurdunu", "Buzkurduyla") +N("Ranger", GEN_M, "Korucu", "Korucular", "Korucuyu","Korucuyla") +N("Rock Troll", GEN_M, "Kaya Trolü", "Kaya Trolleri", "Kaya Trolünü", "Kaya Trolüyle") +N("Goblin", GEN_M, "Goblin", "Goblinler", "Goblini", "Goblinle") +N("Sand Worm", GEN_M, "Kumkurdu", "Kumkurtları", "Kumkurdunu" , "Kumkurduyla") +N("Sand Worm Tail", GEN_M, "Kumkurdu Kuyruğu", "Kumkurdu Kuyrukları", "Kumkurdu Kuyruğunu" , "Kumkurdu Kuyruğuyla") +N("Sand Worm W", GEN_M, "Kumkurdu W", "Kumkurtları W", "Kumkurdunu W", "Kumkurduyla W") +N("Desert Man", GEN_M, "Bedevi", "Bedeviler", "Bedeviyi", "Bedeviyle") +N("Ivy Root", GEN_M, "Sarmaşık Kökü", "Sarmaşık Kökleri", "Sarmaşık Kökünü", "Sarmaşık Köküyle") +N("Active Ivy", GEN_M, "Canlı Sarmaşık", "Canlı Sarmaşıklar", "Canlı Sarmaşığı", "Canlı Sarmaşığıyla") +N("Ivy Branch", GEN_F, "Sarmaşık Dalı", "Sarmaşık Dalları", "Sarmaşık Dalını", "Sarmaşık Dalıyla") +N("Dormant Ivy", GEN_M, "Uyuyan Sarmaşık", "Uyuyan Sarmaşıklar", "Uyuyan Sarmaşığı", "Uyuyan Sarmaşıkla") +N("Ivy N", GEN_M, "sarmaşık N", "Sarmaşıklar N", "Sarmaşığı N" , "Sarmaşıkla N") +N("Ivy D", GEN_M, "Sarmaşık D", "sarmaşıklar D", "Sarmaşığı D", "Sarmaşıkla D") +N("Giant Ape", GEN_F, "Dev Maymun", "Dev Maymunlar", "Dev Maymunu", "Dev Maymunla") +N("Slime Beast", GEN_F, "Balçık Canavarı", "Balçık Canavarları", "Balçık Canavarını", "Balçık Canavarıyla") +N("Mirror Image", GEN_N, "Yansıma", "Yansımalar", "Yansımayı", "Yansımayla") +N("Mirage", GEN_M, "Yansı", "Yansılar", "Yansıyı", "Yansıyla") +N("Golem", GEN_M, "Golem", "Golemler", "Golemi", "Golemle") +N("Eagle", GEN_M, "Kartal", "Kartallar", "Kartalı", "Kartalla") +N("Seep", GEN_M, "Sızıntı", "Sızıntılar", "Sızıntıyı" , "Sızıntıyla") +N("Zombie", GEN_M, "Hortlak", "Hortlaklar", "Hortlağı", "Hortlakla") +N("Ghost", GEN_M, "Hayalet", "Hayaletler", "Hayaleti" , "Hayaletle") +N("Necromancer", GEN_M, "Ölüçağıran", "Ölüçağıranlar", "Ölüçağıranı", "Ölüçağıranla") +N("Shadow", GEN_M, "Gölge", "Gölgeler", "Gölgeyi", "Gölgeyle") +N("Tentacle", GEN_M, "Dokunaç", "Dokunaçlar", "Dokunacı", "Dokunaçla") +N("Tentacle Tail", GEN_M, "Dokunaç Devamı", "Dokunaç Devamları", "Dokunaç Devamını", "Dokunaç Devamıyla") +N("Tentacle W", GEN_M, "Dokunaç W", "Dokunaçlar W", "Dokunacı W", "Dokunaçla W") +N("Cultist", GEN_M, "Mürit", "Müritler", "Müridi", "Müritle") +N("Fire Cultist", GEN_M, "Ateş Müridi", "Ateş Müritleri", "Ateş Müridini", "Ateş Müritle") +N("Greater Demon", GEN_M, "Büyük Şeytan", "Büyük Şeytanlar", "Büyük Şeytanı", "Büyük Şeytanla") +N("Lesser Demon", GEN_M, "Küçük Şeytan", "Küçük Şeytanlar", "Küçük Şeytanı", "Küçük Şeytanla") +N("Ice Shark", GEN_M, "Buz Köpekbalığı", "Buz Köpekbalıkları", "Buz Köpekbalığını", "Buz Köpekbalığıyla") +N("Running Dog", GEN_M, "Koşan Köpek", "Koşan Köpekler", "Koşan Köpeği", "Koşan Köpekle") +N("Demon Shark", GEN_M, "Şeytan Köpekbalığı", "Şeytan Köpekbalıkları", "Şeytan Köpekbalığını","Şeytan Köpekbalığıyla") +N("Fire Fairy", GEN_F, "Ateş Perisi", "Ateş Perileri", "Ateş Perisini", "Ateş Perisiyle") +N("Crystal Sage", GEN_M, "Buz Piri", "Buz Pirleri", "Buz Pirini", "Buz Piriyle") +N("Hedgehog Warrior", GEN_M, "Kirpi Savaşçı", "Kirpi Savaşçılar", "Kirpi Savaşçıyı", "Kirpi Savaşçıyla") +N("Tentacle (withdrawing)", GEN_F, "Dokunaç (geri çekiliyor)", "Dokunaçlar (geri çekiliyor)", "Dokunacı (geri çekiliyor)","Dokunaçla (geri çekiliyor)") +N("Ice Diamond", GEN_O, "Buz Elması", "Buz Elmasları", "Buz Elmasını", "Buz Elmasıyla") +N("Gold", GEN_N, "Altın", "Altınlar", "Altını","Altınla") +N("Spice", GEN_F, "Baharat", "Baharatlar", "Baharatı","Baharatla") +N("Ruby", GEN_O, "Yakut", "Yakutlar", "Yakutu", "Yakutla") +N("Elixir of Life", GEN_O, "Yaşam İksiri", "Yaşam İksirleri", "Yaşam İksirini", "Yaşam İksiriyle") +N("Shard", GEN_O, "Cam Parçası", "Cam Parçaları", "Cam Parçasını", "Cam Parçasıyla") +N("Necromancer's Totem", GEN_O, "Ölüçağıran Totemi", "Ölüçağıran Totemleri", "Ölüçağıran Totemini", "Ölüçağıran Totemiyle") +N("Demon Daisy", GEN_F, "Şeytan Papatyası", "Şeytan Papatyaları", "Şeytan Papatyasını", "Şeytan Papatyasıyla") +N("Statue of Cthulhu", GEN_F, "Cthulhu Heykeli", "Cthulhu Heykelleri", "Cthulhu Heykelini", "Cthulhu Heykeliyle") +N("Phoenix Feather", GEN_N, "Anka Kuşu Tüyü", "Anka Kuşu Tüyleri", "Anka Kuşu Tüyünü", "Anka Kuşu Tüyüyle") +N("Ice Sapphire", GEN_O, "Buz Safiri", "Buz Safirleri", "Buz Safirini", "Buz Safiriyle") +N("Hyperstone", GEN_O, "Aşkıntaş", "Aşkıntaşlar", "Aşkıntaşı", "Aşkıntaşla") +// N("Hyperstone", GEN_O, "Üstüntaş", "Üstüntaşlar", "Üstüntaşı", "Üstüntaşla") +N("Key", GEN_O, "Anahtar", "Anahtarlar", "Anahtarı", "Anahtarla") + N("Dead Orb", GEN_F, "Ölü Küre", "Ölü Küreler", "Ölü Küreyle", "Ölü Küreyi") + +N("Orb of Yendor", GEN_F, "Yendor Küresi", "Yendor Küreleri", "Yendor Küresini", "Yendor Küresiyle") +N("Orb of Storms", GEN_F, "Fırtına Küresi", "Fırtına Küreleri", "Fırtına Küresini", "Fırtına Küresiyle") +N("Orb of Flash", GEN_F, "Şimşek Küresi", "Şimşek Küreleri", "Şimşek Küresini", "Şimşek Küresiyle") +N("Orb of Winter", GEN_F, "Kış Küresi", "Kış Küreleri", "Kış Küresini", "Kış Küresiyle") +N("Orb of Speed", GEN_F, "Hız Küresi", "Hız Küreleri", "Hız Küresini", "Hız Küresiyle") +N("Orb of Life", GEN_F, "Yaşam Küresi", "Yaşam Küreleri", "Yaşam Küresini", "Yaşam Küresiyle") +N("Orb of Shielding", GEN_F, "Kalkan Küresi", "Kalkan Küreleri", "Kalkan Küresini", "Kalkan Küresiyle") +// N("Orb of Digging", GEN_F, "Kazma Küresi", "Kazma Küreleri", "Kazma Küresini", "Kazma Küresiyle") +N("Orb of Teleport", GEN_F, "Işınlanma Küresi", "Işınlanma Küreleri", "Işınlanma Küresini", "Işınlanma Küresiyle") +N("Orb of Safety", GEN_F, "Güvenlik Küresi", "Güvenlik Küreleri", "Güvenlik Küresini", "Güvenlik Küresiyle") +N("Orb of Thorns", GEN_F, "Diken Küresi", "Diken Küreleri", "Diken Küresini", "Diken Küresiyle") + N("Fern Flower", GEN_O, "Eğreltiotu Çiçeği", "Eğreltiotu Çiçekleri", "Eğreltiotu Çiçeğini", "Eğreltiotu Çiçeğiyle") +N("none", GEN_O, "hiç", "hiçler", "hiçi", "hiçle") +N("ice wall", GEN_F, "Buzdan Duvar", "Buzdan Duvarlar", "Buzdan Duvarı", "Buzdan Duvarda") +N("great wall", GEN_F, "Çin Seddi", "Çin Setleri", "Çin Seddini", "Çin Seddinde") +N("red slime", GEN_F, "Kırmızı Balçık", "Kırmızı Balçıklar", "Kırmızı Balçığı", "Kırmızı Balçıkta") +N("blue slime", GEN_F, "Mavi Balçık", "Mavi Balçıklar", "Mavi Balçığı", "Mavi Balçıkta") +N("living wall", GEN_F, "Canlı Duvar", "Canlı Duvarlar", "Canlı Duvarı", "Canlı Duvarda") +N("living floor", GEN_F, "Canlı Zemin", "Canlı Zeminler", "Canlı Zemini", "Canlı Zeminde") +N("dead troll", GEN_M, "Ölü Trol" ,"Ölü Troller", "Ölü Trolü", "Ölü Trolle") +N("sand dune", GEN_F, "Kumul", "Kumullar", "Kumulu", "Kumulda") +N("Magic Mirror", GEN_N, "Sihirli Ayna", "Sihirli Aynalar", "Sihirli Aynayı", "Sihirli Aynayla") +N("Cloud of Mirage", GEN_F, "Bulut Yansısı", "Bulut Yansıları", "Bulut Yansısını", "Bulut Yansısıyla") +N("Thumper", GEN_O, "Gümleyen", "Gümleyenler", "Gümleyeni", "Gümleyenle") +N("Bonfire", GEN_N, "Kamp Ateşi", "Kamp Ateşleri", "Kamp Ateşini", "Kamp Ateşiyle") +N("ancient grave", GEN_O, "Antik Mezar", "Antik Mezarlar", "Antik Mezarı", "Antik Mezarda") +N("fresh grave", GEN_O, "Taze Mezar", "Taze Mezarlar", "Taze Mezarı", "Taze Mezarda") +N("column", GEN_F, "Sütun", "Sütunlar", "Sütunu", "Sütunla") +N("lake of sulphur", GEN_N, "Sülfür Gölü", "Sülfür Gölleri", "Sülfür Gölünü", "Sülfür Gölünde") +N("lake", GEN_N, "Göl", "Göller", "Gölü", "Gölde") +N("frozen lake", GEN_N, "Donmuş Göl", "Donmuş Göller", "Donmuş Gölü", "Donmuş Gölde") +N("chasm", GEN_N, "Uçurum", "Uçurumlar", "Uçurumu", "Uçurumda") +N("big tree", GEN_N, "Büyük Ağaç", "Büyük Ağaçlar", "Büyük Ağacı", "Büyük Ağaçla") +N("tree", GEN_N, "Ağaç", "Ağaçlar", "Ağacı", "Ağaçla") +// "???" +N("Great Wall", GEN_N, "Yüksek Duvar", "Yüksek Duvarlar", "Yüksek Duvarı", "Yüksek Duvarda") +N("Crossroads", GEN_N, "Arayollar", "Arayollar", "Arayolları", "Arayollarda") +N("Desert", GEN_F, "Çöl", "Çöller", "Çölü", "Çölde") +N("Icy Land", GEN_F, "Buz Diyarı", "Buz Diyarları", "Buz Diyarını", "Buz Diyarında") +N("Living Cave", GEN_F, "Yaşayan Mağara", "Yaşayan Mağaralar", "Yaşayan Mağarayı", "Yaşayan Mağarada") +N("Jungle", GEN_F, "Vahşi Orman", "Vahşi Ormanlar", "Vahşi Ormanı", "Vahşi Ormanda") +N("Alchemist Lab", GEN_N, "Laboratuar", "Laboratuarlar", "Laboratuarı", "laboratuarda") +N("Mirror Land", GEN_F, "Aynalar Diyarı", "Aynalar Diyarları", "Aynalar Diyarını", "Aynalar Diyarında") +N("Graveyard", GEN_O, "Mezarlık", "Mezarlıklar", "Mezarlığı", "Mezarlıkta") +// "R'Lyeh" +N("R'Lyeh", GEN_N, "R'Lyeh", "R'Lyeh", "R'Lyeh", "R'Lyeh") +N("Hell", GEN_N, "Cehennem", "Cehennemler", "Cehennemi", "Cehennemde") +N("Cocytus", GEN_M, "Kokitos", "Kokitoslar", "Kokitosu", "Kokitosta") +N("Land of Eternal Motion", GEN_N, "Sonsuz Devinim Diyarı", "Sonsuz Devinim Diyarları", "Sonsuz Devinim Diyarını", "Sonsuz Devinim Diyarında") +N("Dry Forest", GEN_M, "Kara Orman", "Kara Ormanlar", "Kara Ormanı", "Kara Ormanda") +N("Game Board", GEN_F, "Tahta", "Tahtalar", "Tahtayı", "Tahtada") + +// Game messages + +// fighting messages + +// ablative ! + +S("You kill %the1.", "%a1 öldürdün.") +S("You would be killed by %the1!", "%1 tarafından öldürülürsün!") +S("%The1 would get you!", "%1 seni kapar!") +S("%The1 destroys %the2!", "%1 %a2 yok etti!") +S("%The1 eats %the2!", "%1 %a2 yedi!") +S("The ivy destroys %the1!", "Samaşık %a1 yok etti!") +S("%The1 claws %the2!", "%1 %a2 pençeledi!") +S("%The1 scares %the2!", "%1 %a2 korkuttu!") +S("%The1 melts away!", "%1 eridi!") +S("%The1 stabs %the2.", "%1 %2 bıçakladı.") +S("You stab %the1.", "%a1 bıçakladın.") + +S("You cannot attack %the1 directly!", "%a1 doğrudan öldüremezsiniz!") +S("Stab them by walking around them.", "Etrafında yürüyerek bıçaklayın.") + +S("You feel more experienced in demon fighting!", "Şeytanlarla savaşmada daha deneyimli hissediyorsun!") +S("Cthulhu withdraws his tentacle!", "Cthulhu dokungacını çekti!") +S("The sandworm explodes in a cloud of Spice!", "Kumkurdu patladı ve etrafa baharat saçtı!") +S("%The1 is confused!", "%1 sersemledi.") +S("%The1 raises some undead!", "%1 ölü çağırdı!") +S("%The1 throws fire at you!", "%1 sana ateş attı!") +S("%The1 shows you two fingers.", "%1 sana iki parmağını gösterdi.") +S("You wonder what does it mean?", "Bunun ne demek olduğunu merak ettin") +S("%The1 shows you a finger.", "%1 sana parmak hareketi yaptı.") +S("You think about possible meanings.", "Bunun olası anlamlarını düşündün.") +S("%The1 moves his finger downwards.", "%1 parmağını aşağı doğru hareket ettirdi.") +S("Your brain is steaming.", "Beynin kaynıyor.") +S("%The1 destroys %the2!", "%1 %a2 yok etti!") +S("You join %the1.", "%abl1 bütünleştin.") +S("Two of your images crash and disappear!", "İki yansıma çarpıştı ve yok oldu!") +S("%The1 breaks the mirror!", "%1 aynayı kırdı!") +S("%The1 disperses the cloud!", "%1 bulutun içerisinde kayboldu!") +S("You activate the Flash spell!", "Işık büyüsünü etkinleştirdin!") +S("You activate the Lightning spell!", "Şimşek büyüsünü etkinleştirdin!") +S("Ice below you is melting! RUN!", "Altındaki buz eriyor! KAÇ!") +S("This spot will be burning soon! RUN!", "Bu nokta yakında yanacak! KAÇ!") +S("The floor has collapsed! RUN!", "Zemin çöktü! KAÇ!") +S("You need to find the right Key to unlock this Orb of Yendor!", + "Bu Yendorun Küresinin kilidini açmak için bir anahtara ihtiyacın var!") +S("You fall into a wormhole!", "Bir solucan deliğine düştün!") +S("You activate %the1.", "%a1 aktifleştirdin.") +S("No room to push %the1.", "%a1 itmek için yeterince yer yok.") +S("You push %the1.", "%a1 ittirdin.") +S("You start cutting down the tree.", "Ağacı kesmeye başladın.") +S("You cut down the tree.", "Ağacı kestin.") +S("You cannot attack Sandworms directly!", "Kumkurduna doğrudan saldıramazsınız!") +S("You cannot attack Tentacles directly!", "Dokungaçlara doğrudan saldıramazsın!") +S("You cannot defeat the Shadow!", "gölgeyi henüz yenemezsiniz!") +S("You cannot defeat the Greater Demon yet!", "Büyük Şeytanı henüz yenemezsiniz!") +S("That was easy, but groups could be dangerous.", "Bu kolaydı, ama gruplar daha tehlikeli olabilir.") +S("Good to know that your fighting skills serve you well in this strange world.", "Dövüş yeteneklerinin bu garip dünyada hâlâ işe yaradığını bilmek güzel.") +S("You wonder where all these monsters go, after their death...", "Bütün bu canavarların ölümlerinden sonra nereye gittiklerini merak ediyorsun...") +S("You feel that the souls of slain enemies pull you to the Graveyard...", "Katlettiğin düşmanların ruhlarının seni mezarlığa çektiğini hissediyorsun...") +S("Wrong color!", "Yanlış renk!") +//this one is a bit problematic +S("You cannot move through %the1!", "%abl1n geçemezsin!") +S("%The1 would kill you there!", "%1 orada seni hemencecik öldürür!") +S("Wow! %1! This trip should be worth it!", "Vay canına! %1! Bu seyahati yaptığına değecek!") +S("For now, collect as much treasure as possible...", "Şimdilik mümkün olduğunca fazla hazine topla...") +S("Prove yourself here, then find new lands, with new quests...", "Kendini burada kanıtla, sonra yeni görevlerle yeni diyarlar keşfet...") +S("You collect your first %1!", "%a1 topladın. Bu senin ilkin!") +S("You have found the Key! Now unlock this Orb of Yendor!", "Anahtarı buldun! Bu Yendorun Küresinin kilidini açabilirsin!") +S("This orb is dead...", "Bu küre ölü...") +S("Another Dead Orb.", "Başka bir Ölü Küre.") +S("You have found %the1!", "%a1 buldun!") +//THIS ONE IS A BIT PROBLEMATIC +S("You feel that %the2 become%s2 more dangerous.", "Topladığın her %abl1, ...") +S("With each %1 you collect...", "%2 gittikçe daha tehlikeli bir hâl alıyor...") +S("Are there any magical orbs in %the1?...", "%abl1 başka sihirli küre var mı?") +S("You feel that %the1 slowly become%s1 dangerous...", "%1 yavaşça daha tehlikeli bir hâl alıyor...") +S("Better find some other place.", "Başka bir yer bulsan daha iyi olacak.") +S("You have a vision of the future, fighting demons in Hell...", "Geleceğini gördün, Cehennemde şeytanlarla savaşıyordun...") +S("With this Elixir, your life should be long and prosperous...", "Bu İksirle hayatın uzun ve refah olacak...") +S("The Necromancer's Totem contains hellish incantations...", "Ölüçağıranın Totemi şeytani işlemelerle doluydu...") +S("The inscriptions on the Statue of Cthulhu point you toward your destiny...", "Cthulhu'nun heykeli üzerindeki yazıt sana kaderinin nasıl çizileceğini gösteriyor...") +S("Still, even greater treasures lie ahead...", "İleride daha bile çok hazine seni bekliyor...") +S("You collect %the1.", "%a1 aldın.") +S("CONGRATULATIONS!", "TEBRIKLER!") +S("Collect treasure to access more different lands...", "Başka diyarlara ulaşmak için hazine topla...") +S("You feel that you have enough treasure to access new lands!", "Yeni diyarlara ulaşmak için yeterince hazinen olduğunu düşünüyorsun!") +S("Collect more treasures, there are still more lands waiting...", "Daha fazla hazine topla, hâlâ seni bekleyen diyarlar var...") +S("You feel that the stars are right, and you can access R'Lyeh!", "Yıldızlar sana, R'Lyeh'e ulaşabileceğini söylüyor!") +S("Kill monsters and collect treasures, and you may get access to Hell...", "Canavarlar öldür, hazineler topla ve belki Cehenneme erişebilirsin...") +S("To access Hell, collect 10 treasures each of 9 kinds...", "Cehenneme erişmek için her 9 hazine tipinden 10'ar tane toplamalısın...") +S("Abandon all hope, the gates of Hell are opened!", "Umutlar tükendi, Cehennemin kapıları açıldı!") +S("And the Orbs of Yendor await!", "Yendorun Küresi seni bekliyor!") +S("You switch places with %the1.", "%abl1 yer değiştirdin.") +S("You rejoin %the1.", "%abl1 bütünleştin.") +S("The mirror shatters!", "Ayna kırıldı!") +S("The cloud turns into a bunch of images!", "Bulut pek çok görüntüye dönüştü!") +S("The slime reacts with %the1!", "Balçık %abl1 etkileşime girdi!") +S("You drop %the1.", "%a1 düşürdün.") +S("You feel great, like a true treasure hunter.", "Şahane hissediyorsun. Sanki gerçek bir hazine avcısı gibi.") +S("Your eyes shine like gems.", "Gözlerin mücevherler gibi ışıldıyor.") +S("Your eyes shine as you glance at your precious treasures.", "Değerli hazinelerine bakarken gözlerin ışıldadı.") +S("You glance at your great treasures.", "Müthiş hazinelerine göz gezdirdin.") +S("You glance at your precious treasures.", "Değerli hazinelerine şöyle bir baktın.") +S("You glance at your precious treasure.", "Hazinene şöyle bir baktın.") +S("Your inventory is empty.", "Envanterin boş.") +S("You teleport to a new location!", "Yeni bir yere ışınlandın!!") +S("Could not open the score file: ", "Puan dosyası açılamadı: ") +S("Game statistics saved to %1", "İstatistikler %1 konumuna kaydedildi.") +S("Game loaded.", "Oyun yüklendi.") +S("You summon some Mimics!", "Taklitçiler çağırdın!") +S("You summon a golem!", "Bir golem çağırdın!") +S("You will now start your games in %1", "Şimdi oyunlarını %abl1 başlatacaksın.") +S("Activated the Hyperstone Quest!", "Aşkıntaş Görevini etkinleştirdin!") +S("Orb power depleted!", "Küre gücü tükendi!") +S("Orbs summoned!", "Küreler çağırdın!") +S("Orb power gained!", "Küre gücü kazandın!") +S("Dead orbs gained!", "Ölü Küreler kazandın!") +S("Orb of Yendor gained!", "Yendorun Orbu kazandın!") +S("Treasure gained!", "Hazine kazanıldı!") +S("Lots of treasure gained!", "Bir sürü hazine kazandın!") +S("You summon a sandworm!", "Bir kumkurdu çağırdın!") +S("You summon an Ivy!", "Bir sarmaşık oluşturdun!") +S("You summon a monster!", "Bir canavar oluşturdun!") +S("You summon some Thumpers!", "Gümleyenler oluşturdun") +S("You summon a bonfire!", "Bir kamp ateşi oluşturdun!") +S("Treasure lost!", "Hazine kayboldu!") +S("Kills gained!", "Leşler kazandınız!") +S("Activated Orb of Safety!", "Güvenlik Küresini aktifleştirdin.") +S("Teleported to %1!", "%loc1 e ışınlandın.") + +S("Welcome to HyperRogue", "HyperRogue'a hoşgeldin") +S(" for Android", " Android için") +S(" for iOS", " iOS için") +S("! (version %1)\n\n", "! (versiyon %1)\n\n") +S(" (press ESC for some hints about it).", " (ESC ile hakkında yardıma ulaşabilirsin).") +S("Press 'c' for credits.", "Yapımcılar için 'c'ye bas.") +S("game design, programming, texts and graphics by Zeno Rogue \n\n", + "tasarım, programlama, metinler ve grafikler: Zeno Rogue \n\n") +S("add credits for your translation here", "Çeviri: zulmetefza & Seyacim\n\n") +S(" (touch to activate)", " (etkinleştirmek için dokun)") +S(" (expired)", " (zaman aşımı)") +S(" [%1 turns]", " [Tur: %1]") +S(", you", ", Sen") +S("0 = Klein model, 1 = Poincaré model", "0 = Klein modeli, 1 = Poincaré modeli") +S("you are looking through it!", "Hiperboloidin içinden bakıyorsun!") +S("simply resize the window to change resolution", "pencerenin boyutunu değiştirerek çözünürlüğü değiştirebilirsin.") +S("[+] keep the window size, [-] use the screen resolution", "[+] pencere boyutunu koru, [-] ekran çözünürlüğünü kullan") +S("+5 = center instantly, -5 = do not center the map", "+5 = anında merkeze al, -5 = merkezleme") +S("press Space or Home to center on the PC", "Space veya Home'a basarak PC'ye odakla.") +S("You need special glasses to view the game in 3D", "Oyunu 3D'de görüntülemek için özel gözlüklere ihtiyacın var.") +S("You can choose one of the several modes", "Farklı modlardan birini seçebilirsin.") +S("ASCII", "ASCII") +S("black", "siyah") +S("plain", "düz") +S("Escher", "Escher") +S("items only", "tylko przedmioty") +S("items and monsters", "eşyalar ve canavarlar") +S("no axes", "eksen yok") +S("auto", "otomatik") +S("light", "hafif") +S("heavy", "ağır") +S("The axes help with keyboard movement", "Eksenler klavye hareketine yardım eder.") +S("Config file: %1", "Ayar dosyası: %1") +S("joystick mode: automatic (release the joystick to move)", "oyun kolu modu: otomatik (kolu bırakarak hareket edersin)") +S("joystick mode: manual (press a button to move)", "oyun kolu modu: manuel (bir düğmeye basarak hareket edersin)") +S("Reduce the framerate limit to conserve CPU energy", "CPU enerjisinden tasarruf etmek için kare sayısı sınırını azalt.") +S("Press F1 or right click for help", "F1 ya da sağ tık ile yardıma ulaş.") +S("No info about this...", "Hakkında bir bilgi yok...") +S("Press Enter or F10 to save", "Enter ya da F10 ile kayıt et") +S("Press Enter or F10 to quit", "Enter ya da F10 ile çık") +S("or 'r' or F5 to restart", "'r' veya F5 ile yeniden başlat") +S("or 't' to see the top scores", "'t' ile yüksek puanları gör") +S("or another key to continue", "veya devam etmek için başka bir tuşa bas.") +S("It is a shame to cheat!", "Seni Hilekâr!") +S("Showoff mode", "Gösteriş Modu") +S("Quest status", "Görev durumu") +S("GAME OVER", "OYUN BİTTİ") +S("Your score: %1", "Puanın: %1") +S("Enemies killed: %1", "Öldürülen Düşmanlar: %1") +S("Orbs of Yendor found: %1", "Bulunan Yendor Küresi sayısı: %1") +S("Collect 30 $$$ to access more worlds", "30 $$$ toplayarak başka dünyalara eriş") +// S("Collect 60 $$$ to access R'Lyeh and Dry Forest", "60 $$$ toplayarak R'Lyeh ve Kara Ormana eriş.") +S("Collect at least 10 treasures in each of 9 types to access Hell", "9 hazine çeşidinin hepsinden 10'ar tane toplayarak Cehenneme erişebilirsin.") +S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "10 Şeytan Papatyası toplayarak Yendorun Kürelerini bulabilirsin.") +S("Hyperstone Quest: collect at least 10 %1 in %the2", "Aşkıntaş Görevi: %2'de en az 10 hazine topla.") +S("Hyperstone Quest completed!", "Aşkıntaş görevi tamamlandı.") +S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Yendorun Küreleri için Cehennemi yahut Arayolları ara!") +S("Unlock the Orb of Yendor!", "Yendor'un küresinin kilidini aç!") +S("Defeat 100 enemies to access the Graveyard", "Mezarlığa erişmek için 100 düşman öldür.") +S("(press ESC during the game to review your quest)", "(Görevine bakmak için oyun sırasında ESC'ye bas.)") +S("you have cheated %1 times", "şimdiye kadar %1 kez hile yaptın.") +S("%1 turns (%2)", "tur sayısı: %1 (%2)") +S("last messages:", "son mesajlar: ") +S("time elapsed", "geçen zaman") +S("date", "tarih") +S("treasure collected", "toplanan hazineler") +S("total kills", "toplam leşler") +S("turn count", "tur sayacı") +S("cells generated", "üretilen hücreler") +S("t/left/right - change display, up/down - scroll, s - sort by", "t/sol/sağ - görünümü değiştir, yukarı/aşağı - kaydır, s - sırala") +S("kills", "leşler") +S("time", "zaman") +S("ver", "ver") +S("SORT", "SIRALA") +S("PLAY", "OYNA") +S("Your total wealth", "Toplam servetiniz") +S("treasure collected: %1", "toplanan hazine: %1") +S("objects found: %1", "bulunan eşyalar: %1") +S("orb power: %1", "küre gücü: %1") +S(" (click to drop)", " (bırakmak için tıkla)") +S("You can also scroll to the desired location and then press 't'.", "İstersen görüntüyü isteidğin yere çekip sonra 't'ye basabilirsin.") +S("Thus, it is potentially useful for extremely long games, which would eat all the memory on your system otherwise.\n", + "Yani, bu olası çok uzun, sistemin tüm hafızasını tüketecek oyunlarında yardımcı olabilir.") +S("You can touch the Dead Orb in your inventory to drop it.", "Ölü Küreye dokunarak onu bırakabilirsin.") +S("This might be useful for Android devices with limited memory.", "Bu, sınırlı hafızalı Android cihazları için kullanışlı olabilir.") +S("You can press 'g' or click them in the list to drop a Dead Orb.", "'g' ye basarak veya listede tıklayarak bir Ölü Küreyi bırakabilirsin.") +S("frames per second", "saniye başına kare") +S("monsters killed: %1", "öldürülen canavarlar: %1") +S("Drawing %1 (layer %2), F1 for help", "%1 çiziliyor (katman %2), F1 - yardım") +S("hepta floor", "heptazemin") +S("hexa floor", "hekzazemin") +S("character", "karakter") +S("ESC for menu/quest", "ESC - menü/görev") +S("vector graphics editor", "vektör grafiği editörü") +S("cheat mode", "hile modu") +S("heptagonal game board", "yedigensel tahta") +S("triangular game board", "üçgensel tahta") +S("HyperRogue game board", "HyperRogue tahta") +S("first page [Space]", "ilk sayfa [Space]") +S("exit configuration", "ayarlardan çık") +S("Configuration:", "AYARLAR:") +S("video resolution", "çözünürlük") +S("fullscreen mode", "tam ekran modu") +S("animation speed", "animasyon hızı") +S("dist from hyperboloid ctr", "hiperboloid merkezinden uzaklık") +S("scale factor", "ölçek faktörü") +S("wall display mode", "duvar görünümü") +S("monster display mode", "canavar görünümü") +S("cross display mode", "yıldız görünümü") +S("background music volume", "müzik seviyesi") +S("OFF", "KAPALI") +S("ON", "AÇIK") +S("distance between eyes", "gözler arası uzaklık") +S("framerate limit", "kare sayısı sınırı") +S("joystick mode", "oyun kolu modu") +S("automatic", "otomatik") +S("manual", "kılavuz") +S("language", "dil") +S("EN", "TR") +S("player character", "oyuncunun karakteri") +S("male", "erkek") +S("female", "kadın") +S("use Shift to decrease and Ctrl to fine tune ", "Shift'le azalt, Ctrl ile ince ayar yap.") +S("(e.g. Shift+Ctrl+Z)", " (Meselâ Shift+Ctrl+Z)") +S("the second page [Space]", "ikinci sayfa [Space]") +S("special features [Space]", "özel seçenekler [Space]") +S("exit configuration", "ayarlardan çık.") +S("see the help screen", "yardım ekranına bak.") +S("save the current config", "mevcut ayarları kaydet") +S("(v) config", "(v) ayarlar") +S("Screenshot saved to %1", "Ekran görüntüsü %1 konumuna kaydedildi.") +S("You need an Orb of Teleport to teleport.", "Işınlanmak için Işınlanma Küresine ihtiyacın var.") +S("Use arrow keys to choose the teleport location.", "Işınlanacağın yeri seçmek için okları kullan.") +S("openGL mode enabled", "OpenGL modu devrede") +S("openGL mode disabled", "OpenGL modu devredışı") +S("anti-aliasing enabled", "Anti=alising devrede/") +S("anti-aliasing disabled", "Anti-aliasing devredışı") +S("You activate your demonic powers!", "Şeytani güçlerini aktifleştirdin!") + +// Steam messages + +S("New Achievement:", "Yeni Başarım:") +S("Your total treasure has been recorded in the Steam Leaderboards.", "Toplam hazinen Steam Listelerine kaydedildi.") +S("Congratulations!", "Tebrikler!") +S("You have improved your total high score and %1 specific high scores!", "Toplam yüksek puanını ve %1 farklı tekil puanını artırdın!") +S("You have improved your total and '%1' high score!", "Toplam yüksek puanını ve '%P1!' puanını artırdın!") +S("You have improved your total high score on Steam. Congratulations!", "Steam'deki toplam yüksek puanını artırdın. Tebrikler!") +//S("You have improved %1 of your specific high scores!", "Tekil yüksek skorlarınızdan %1 tanesini artırdın !") +S("You have improved %1 of your specific high scores!", "Tekil yüksek skorlarından %1 tanesini artırdın !") +S("You have improved your '%1' high score on Steam!", "Steam'deki '%P1'puanını artırdın!") +S("You have collected 10 treasures of each type.", "her hazine çeşidinden onar tane topladın.") +S("This is your first victory!", "Bu senin ilk zaferin!") +S("This has been recorded in the Steam Leaderboards.", "Bu Steam Listelerine kaydedildi.") +S("The faster you get here, the better you are!", "Daha hızlı demek, daha iyi demek !") +S("You have improved both your real time and turn count. Congratulations!", "Hem gerçek zamanını hem de tur sayını geliştirdin! Tebrikler! ") +S("You have used less real time than ever before. Congratulations!", "Bu her zamankinden daha az zaman aldı! Tebrikler!") +S("You have used less turns than ever before. Congratulations!", "Her zamankinden daha az sayıda tur kullandın! Tebrikler! ") + +// help texts. These are separated into multiple lines just for convenience, +// you don't have to follow. + +S( + "You have been trapped in a strange, non-Euclidean world. Collect as much treasure as possible " + "before being caught by monsters. The more treasure you collect, the more " + "monsters come to hunt you, as long as you are in the same land type. The " + "Orbs of Yendor are the ultimate treasure; get at least one of them to win the game!", + +"Garip ve Ökliddışı bir dünyada hapsoldun. Canavarlar tarafından yakalanmadan önce olabildiğince hazine topla." + "Aynı arazi tipinde daha fazla hazine topladıkça,daha fazla canavar sana saldıracak." + "Yendor'un küreleri nihai hazinelerdir, onlardan bir tane ile oyunu kazanabilirsin!" + ) + +S( + "You can fight most monsters by moving into their location. " + "The monster could also kill you by moving into your location, but the game " + "automatically cancels all moves which result in that.\n\n", + + "Çoğu canavarın yerine ilerleyerek onu öldürebilirsin. Canavar da seni senin bulunduğun yere ilerleyerek öldürebilir, ama oyun böyle hamlelere zaten izin vermez.\n\n") + +S( + "Usually, you move by touching somewhere on the map; you can also touch one " + "of the four buttons on the map corners to change this (to scroll the map " + "or get information about map objects). You can also touch the " + "numbers displayed to get their meanings.\n", + "Normalde haritada bir yere dokunarak hareket edersin, haritanın dört köşesindeki tuşlara dokunarak bunu değiştirebilirsin." +" (haritayı çevirmek ya da haritadaki nesneler hakkında bilgi almak için). Gösterilen numaralara dokunarak da anlamlarını görebilirsin. \n") + +S("Move with mouse, num pad, qweadzxc, or hjklyubn. Wait by pressing 's' or '.'. Spin the world with arrows, PageUp/Down, and Home/Space. " + "To save the game you need an Orb of Safety. Press 'v' for config, ESC for the quest status and menu.\n\n", + "Fareyle, sayı tuşlarıyla, qweadzxc ile, veya hjklyubn ile hareket et. 's' ya da '.' ile bekle. " + "Oklarla, PageUp/Down ile veya Home/Space ile dünyayı çevirebilirsin. Oyunu kaydetmek için Güvenlik Küresine ihtiyacın var. Ayarlar için 'v'ye görev durumu ve menü için 'ESC'ye bas.\n\n") + +S("See more on the website: ", "Daha fazlasını websitesinde görüntüleyin: ") + +S( + "special thanks to the following people for their bug reports, feature requests, porting, and other help:\n\n%1\n\n", + "Hata bildirimleri, özellik istekleri, portlama ve diğer yardımları için şu kişilere teşekkürler: %1 \n\n") + +S( + "The total value of the treasure you have collected.\n\n" + "Every world type contains a specific type of treasure, worth 1 $$$; " + "your goal is to collect as much treasure as possible, but every treasure you find " + "causes more enemies to hunt you in its native land.\n\n" + "Orbs of Yendor are worth 50 $$$ each.\n\n", + + "Topladığınız hazinelerin toplam değeri.\n\n" + "Her dünya 1 $$$ değerinde belli bir çeşit hazine içerir; " + "amacın olabildiğince çok hazine toplamak, ama her bulduğun hazine, daha fazla düşmanın sana saldırmasına sebep olur.\n\n " + "Her Yendorun Küresi 50 $$$ değerindedir.\n\n") + +S( + "The higher the number, the smoother the animations in the game. " + "If you find that animations are not smooth enough, you can try " + "to change the options ", + "Daha yüksek sayı, daha akıcı animasyonlr demektir. " + "Eğer animasyonlar senin için yeterince akıcı değilse, ayarları değiştirmeyi düşünebilirsin") + +S("(Menu button) and select the ASCII mode, which runs much faster. " + "Depending on your device, turning the OpenGL mode on or off might " + "make it faster, slower, or cause glitches.", + "(Menü), ve ASCII modunu seçebilirsin. Bu mod daha hızlı çalışır. Aygıtınıza bağlı olarak OpenGL'yi açmak oyununuzu hızlandırabilir, yavaşlatabilir veya hatalara sebep olabilir." + ) + +S("(in the MENU). You can reduce the sight range, this should make " + "the animations smoother.", + "(MENÜDE). Görüş aralığını seçebilirsin. Bu animasyonları daha akıcı hâle getirebilir.") + +S("(press v) and change the wall/monster mode to ASCII, or change " + "the resolution.", + "('v'ye bas) ve duvar ve canavar modunu ASCII'ye çevir veya çözünnürlüğü değiştir.") + +S( + "In this mode you can draw your own player character and floors. " + "Mostly for the development purposes, but you can have fun too.\n\n" + "f - floor, p - player (repeat 'p' for layers)\n\n" + "n - new shape, u - copy the 'player body' shape\n\n" + "1-9 - rotational symmetries, 0 - toggle axial symmetry\n\n" + "point with mouse and: a - add point, m - move nearest point, d - delete nearest point, c - nearest point again, b - add after nearest\n\n" + "s - save in C++ format (but cannot be loaded yet without editing source)\n\n" + "z - zoom, o - Poincaré model\n", + + "Bu modda, kendi karakterini ve zemini çizebilirsin. " + "Aslında geliştirme amaçları için vri ama eğlence için de kullanabilirsin.\n\n" + "f - zemin, p - oyuncu (katman eklemek için 'p'ye tekrar bas)\n\n" + "n - yeni şekil, u - oyuncu şeklini kopyala\n\n" + "1-9 - döngüsel simetriler, 0 - eksensel simetriyi aç/kapa\n\n" + "fareyle göster ve: a - nokta ekle, m - en yakındaki noktaya git, d - en yakındaki noktayı sil, c - tekrar en yakın nokta, b - en yakından sonraya ekle\n\n" + "s - C++ formatında sakla (ancak kaynağı düzenlemeden yüklenemez)\n\n" + "z - yakınlaş, o - Poincaré modeli\n") + +S( + "These huge monsters normally live below the sand, but your movements have " + "disturbed them. They are too big to be slain with your " + "weapons, but you can defeat them by making them unable to move. " + "This also produces some Spice. They move two times slower than you.", + + "Normalde bu canavarlar yer altında yaşarlar ama hareketlerin onları rahatsız etti. " + "Bıçağınla kesilmek için fazla iriler, ama onları hareket edemez hale getirerek yenebilirsin. " + "Bu biraz Baharat da üretir. Senden iki kat yavaş hareket ederler.") + +S("The tentacles of Cthulhu are like sandworms, but longer. " + "They also withdraw one cell at a time, instead of exploding instantly.", + "Cthulhu'nun dokunaçları kumkurtları gibidir, ama daha uzundur. Ve birden patlamak yerine her seferinde bir hücregeri çekilirler.") + +S( + "A huge plant growing in the Jungle. Each Ivy has many branches, " + "and one branch grows per each of your moves. Branches grow in a clockwise " + "order. The root itself is vulnerable.", + "Vahşi Ormanda büyüyen devasa bir bitki. Her sarmaşığın bir sürü dalı vardır ve senin her hareketinle bir dal büyür. Dallar saatyönü sırasında büyür. Kökün kendisi savunmasızdır. \n") + +S("The Alchemists produce magical potions from pools of blue and red slime. You " + "can go through these pools, but you cannot move from a blue pool to a red " + "pool, or vice versa. Pools containing items count as colorless, and " + "they change color to the PC's previous color when the item is picked up. " + "Slime beasts also have to keep to their own color, " + "but when they are killed, they explode, destroying items and changing " + "the color of the slime and slime beasts around them.", + "Simyacılar mavi ve kırmızı balçık havuzlarından sihirli iksirler üretirler. " + "Bu havuzlardan geçebilirsin, ama kırmızı bir havuzdan mavi bir havuza veya tam tersine geçemezsin. " + "Balçık canavarları kendi renklerinde durmak zorundadır, " + "Ama öldüklerinde patlarlar ve etrafındaki eşyaları yok eder, etraflarındaki balçığın ve canavarların rengini değiştirirler. \n") + +S( + "These creatures are slow, but very powerful... more powerful than you. " + "You need some more experience in demon fighting before you will be able to defeat them. " + "Even then, you will be able to slay this one, but more powerful demons will come...\n\n" + "Each 10 lesser demons you kill, you become powerful enough to kill all the greater " + "demons on the screen, effectively turning them into lesser demons.", + + "Bu yaratıklar yavaştır ama çok güçlüdür. Senden bile. " + "Bunları yenebilmek için öncesinde şeytanlarla savaşma konusunda tecrübeli olman gerekir. " + "O zaman bile, bunu yenebilirsin, ama daha güçlü şeytanlar gelecektir...\n\n" + "Öldürdüğün her 10 küçük şeytan için, ekrandaki bütün Büyük Şeytanları -sanki onlar da küçükmüş gibi- öldürebilirsin.") + +S("These creatures are slow, but they often appear in large numbers.", + "Bu yaratıklar yavaştır ama genellikle sürü halinde gezerler.") + +S("A big monster from the Living Caves. A dead Troll will be reunited " + "with the rocks, causing some walls to grow around its body.", + "Yaşayan Mağaralardan büyük bir canavar. Ölü bir Trol etrafında yükselen duvarlarla kayalarla yeniden bütünleşir. ") + +S("Huge, impassable walls which separate various lands.", + "Farklı diyarları birbirinden ayıran çok yüksek, aşılamaz duvarlar.") + +S( + "This cave contains walls which are somehow living. After each turn, each cell " + "counts the number of living wall and living floor cells around it, and if it is " + "currently of a different type than the majority of cells around it, it switches. " + "Items count as three floor cells, and dead Trolls count as five wall cells. " + "Some foreign monsters also count as floor or wall cells.\n", + "Bu mağara nasılsa yaşayan duvarlarla kaplıdır. Her tur her hücre çevresindeki yaşayan zemin ve yaşayan duvar hücrelerini sayar ve eğer çevresindeki çoğunluktan farklı bir türdeyse çoğunluğa dönüşür. " + "Eşyalar üç zemin hücresi, ölü Troller beş duvar hücresi olarak sayılır.\n") + +S( + "This forest is quite dry. Beware the bushfires!\n" + "Trees catch fire on the next turn. The temperature of the grass cells " + "rises once per turn for each fire nearby, and becomes fire itself " + "when its temperature has risen 10 times.\n" + "You can also cut down the trees. Big trees take two turns to cut down.", + "Bu orman epey kuru. Çalı yangınlarına dikkat et!\n" + "Ağaçlar her tur ateşe yakalanır. Çimen hücrelerinin ısısı her tur yakındaki ateşle bir artar ve sonra ısısı 10 kez yükselirse, kendisi ateş olur.\n " + "Ağaçları kesebilirsin. Büyük ağaçları kesmesi 2 tur alır.\n ") + +S("A big and quite intelligent monster living in the Icy Land.", + "Buz Diyarlarında yaşayan büyük ve epey zeki bir canavar.") + +S( + "A nasty predator from the Icy Land. Contrary to other monsters, " + "it tracks its prey by their heat.", + "Buz Diyarlarında yaşayan hınzır bir yırtıcı. Diğer canavarların aksine, avını ısısıyla takip ediyor.") + +S("Rangers take care of the magic mirrors in the Land of Mirrors. " + "They know that rogues like to break these mirrors... so " + "they will attack you!", + "Seyyahların aynalarını kıracağını bildiklerinden sana saldıracaklar!") + +S("A nasty creature native to the Living Caves. They don't like you " + "for some reason.", + "Yaşayan Mağaralarda yaşayan iğrenç bir yaratık. Nedense seni hiç sevmiyor.") + +S("A tribe of men native to the Desert. They have even tamed the huge Sandworms, who won't attack them.", + "Çölde yaşayan bir insan jabilesi. Büyük Kumkurtlarını evcilleştirip kendilerine saldırmamasını sağladılar.") + +S("This giant ape thinks that you are an enemy.", "Bu devasa maymun senin bir düşman olduğunu düşünüyor.") + +S("A magical being which copies your movements.", "Hareketlerini taklit eden bir büyülü varlık.") + +S("A magical being which copies your movements. " + "You feel that it would be much more useful in an Euclidean space.", + "Hareketlerini taklit eden bir büyülü varlık. Bunların Öklid uzayında daha işe yarayacağını düşünmeden edemiyorsun .") + +S("You can summon these friendly constructs with a magical process.", + "Bu dost mekanizmaları büyüsel bir işlemle uyandırabilirsin.") + +S("A majestic bird, who is able to fly very fast.", + "Çok hızlı uçabilen görkemli bir kuş.") + +S("A monster who is able to live inside the living cave wall.", + "Yaşayan mağara duvarlarında yaşayabilen bir canavar.") + +S("A typical Graveyard monster.", "Mezarlıkta sık rastlanan bir canavar.") + +S("A typical monster from the Graveyard, who moves through walls.\n\n" + "There are also wandering Ghosts. They will appear " + "if you do not explore any new places for a long time (about 100 turns). " + "They can appear anywhere in the game.", + "Mezarlıkta sık rastlanan bir canavar. Duvarlardan geçebilir.\n\n" + "Ayrıca amaçsızca gezinen hayaletler var. Uzunca bir süre (100 tur kadar) yeni diyarlar keşfetmediğinde karşına çıkarlar. Oyundaki herhangi bir yerde karşına çıkabilirler." + ) + +S("Necromancers can raise ghosts and zombies from fresh graves.", + "Ölüçağıranlar mezarlardan hayaletler ve hortlaklar çağırabilirler.") + +S("A creepy monster who follows you everywhere in the Graveyard.", + "Seni Mezarlık boyunca takip eden ürpertici bir canavar.") + +S("People worshipping Cthulhu. They are very dangerous.", + "Cthulhu'ya tapan insanlar. Çok tehlikeliler.") + +S("People worshipping Cthulhu. This one is especially dangerous, " + "as he is armed with a weapon which launches fire from afar.", + "Cthulhu'ya tapan insanlar. Bu özellikle tehlikeli ve uzaktan ateş atabilmesini sağlayan bir silahı var.") + +S("This dangerous predator has killed many people, and has been sent to Cocytus.", + "Bu tehlikeli yırtıcı çok kişiyi öldürdü ve Kokitos'a gönderildi.") + +S("This white dog is able to run all the time. It is the only creature " + "able to survive and breed in the Land of Eternal Motion.", + "Bu beyaz köpek hiç durmadan koşabilir. Sonsuz hareket diyarında yaşayabilen ve çoğalabilen tek canlıdır.") + +S("Demons of Hell do not drown when they fall into the lake in Cocytus. " + "They turn into demonic sharks, enveloped in a cloud of steam.", + "Cehennem Şeytanları Kokitos'ta göle düştüklerinde boğulmazlar." + "Bir buhar bulutuyla kaplı şeytanî köpekbalıklarına dönüşürler.") + +S("These fairies would rather burn the forest, than let you get some Fern Flowers. " + "The forest is infinite, after all...\n\n" + "Fire Fairies transform into fires when they die.", + "Bu periler ormanı yakma pahasına, kimsenin Eğreltiotu Çiçeklerine dokunmasına izin vermezler." + "Sonuçta orman sonsuza kadar uzanıyor...\n\n" + "Ateş perileri öldüklerinde ateşe dönüşürler.") + +S("These warriors of the Forest wield exotic weapons called hedgehog blades. " + "These blades protect them from a frontal attack, but they still can be 'stabbed' " + "easily by moving from one place next to them to another.", + "Ormandaki bu savaşçılar, adına kirpi bıçağı denen ilginç bıçaklar taşıyorlar. Bu bıçaklar onları önden gelen saldırılardan korur, ama hâlâ yanlarından geçerek öldürülebilirler.") + +S("This being radiates an aura of wisdom. " + "It is made of a beautiful crystal, you would love to take it home. " + "But how is it going to defend itself? Better not to think of it, " + "thinking causes your brain to go hot...\n\n" + "Crystal Sages melt at -30 °C, and they can rise the temperature around you from afar.", + "Muhteşem bir kristalden yapılmış, eve götürmeyi çok isterdin." + "Ama kendini nasıl savunacak? Düşünmesen daha iyi, " + "sadece düşünmek bile beynini zorluyor. ...\n\n" + "Kristal Pirleri -30 °C'de erir ve etrfındaki ısıyı uzaktan artırabilir.") + +S("Cold white gems, found in the Icy Land.", "Buz Diyarlarında bulunan soğuk beyaz mücevherler.") + +S("An expensive metal from the Living Caves. For some reason " + "gold prevents the living walls from growing close to it.", + "Yaşayan Mağaralardan pahalı br metal. Anlaşılamayan bir sebeple altın yaşayan duvarları kendine yaklaştırmıyor.") + +S("A rare and expensive substance found in the Desert. " + "It is believed to extend life and raise special psychic powers.", + "Çölde bulunan ender ve pahalı bir katkı maddesi. Yaşamı uzattığına ve bazı özel psişik güçleri açığa çıkardığına inanılıyor.") + +S("A beautiful gem from the Jungle.", "Vahşi Ormandan elde edilmiş bir mücevher.") + +S( + "A wonderful beverage, apparently obtained by mixing red and blue slime. You definitely feel more " + "healthy after drinking it, but you still fell that one hit of a monster is enough to kill you.", + "Şahane bir içki, görünen o ki kırmızı ve mavi balçığın karıştırılmasıyla elde edilmiş. İçince daha sağlıklı hissediyorsun ama bir canavarın tek vuruşunun seni öldüreceğine de eminsin.") + +S("A piece of a magic mirror, or a mirage cloud, that can be used for magical purposes. Only mirrors and clouds " + "in the Land of Mirrors leave these.", + "Sihirli aynanın veya yansı bulutunun bir parçası. Sihirli amaçlar için kullanılabilir. Sadece aynalar ve bulutlardan düşer.") + +S("These sinister totems contain valuable gems.", + "Bu tekinsiz totemler değerli mücevherler içeriyor.") + +S("These star-shaped flowers native to Hell are a valuable alchemical component.", + "Cehennemde yetişen bu yıldız şekilli çiçekler değerli bir simya bileşeni.") + +S("This statue is made of materials which cannot be found in your world.", + "Bu heykel, senin geldiğin dünyada bulunamayacak maddelerden yapılmış.") + +S("One of few things that does not cause the floor in the Land of Eternal Motion to collapse. Obviously they are quite valuable.", + "Hareketler Diyarında yerlerin çökmemesini sağlayan ender şeylerden biri. Bunlar, tabi ki epey değerli.") + +S("Cold blue gems, found in the Cocytus.", "Mavi soğuk mücevherler sadece Kokitos'ta bulunabilir.") + +S("These bright yellow gems can be found only by those who have mastered the Crossroads.", + "Bu sarı parlak mücevherler Arayollarda yeterince deneyim kazananlar tarafından bulunabilir.") + +S("That's all you need to unlock the Orb of Yendor! Well... as long as you are able to return to the Orb that this key unlocks...\n\n" + "Each key unlocks only the Orb of Yendor which led you to it.", + "Yendorun Küresinin kilidini açmak için ihtiyacınız olan her şeyi tamamladın. Tabi... Önce Küreyr dönmen gerekiyor...\n" + "Her anahtar seni ona yönlendiren yendorun küresini açacaktır.") + +S("These orbs can be found in the Graveyard. You think that they were once powerful magical orbs, but by now, their " + "power is long gone. No way to use them, you could as well simply drop them...\n\n", + "Bu küreler Mezarlıkta bulunabilir. Eskiden kudretli sihrili kürelerdi, ama şimdi güçleri bitti. Onları kullanmanın bir yolu yok, bırakın gitsin...\n\n") + +S( + "This wonderful Orb can only be collected by those who have truly mastered this hyperbolic universe, " + "as you need the right key to unlock it. Luckily, your psychic abilities will let you know " + "where the key is after you touch the Orb.", + "Bu harika Küre kilidini açmak için doğru anahtarı gerektirdiğinden, sadece bu hiperbolik evrende tamamen ustalaşmış kişilerce toplanabilir." + "Çok şükür, küreye dokununca psişik yeteneklerin sana anahtarın nerede olduğunu söyler.") + +S( + "This orb can be used to invoke the lightning spell, which causes lightning bolts to shoot from you in all directions.", + "Bu küre şimşek büyüsünü kullanmaya yarar, senden her yöne doğru kıvılcımlar saçılır.") + +S("This orb can be used to invoke a flash spell, which destroys almost everything in radius of 2.", + "Bu küre ışık büyüsünü kullanmaya yarar. Işık büyüsü, 2 hücre uzaklıktaki her şeyi yok eder.") + +S("This orb can be used to invoke a wall of ice. It also protects you from fires.", + "Bu küre bir buz duvarı oluşturmaya yarar. Aynı zamanda seni ateşten korur") + +S("This orb can be used to move faster for some time.", + "Bu küre bir süreliğine daha hızlı hareket etmeye yarar.") + +S("This orb can be used to summon friendly golems. It is used instantly when you pick it up.", + "Bu küre size dost golemler çağırmak için kullanılır. Onu eline aldığında anında kullanılır.") + +S("This orb can protect you from damage.", "Bu küre seni hasardan korur.") + +S("This orb lets you go through living walls. It also has powers in some of the other lands.", + "Bu küre Yaşayan Duvarların içinden geçebilmenizi sağlar.")//Sadece Yaşayan Mağaralarda işe yarar.") + +S("This orb lets you instantly move to another location on the map. Just click a location which " + "is not next to you to teleport there. ", + "Bu küre haritadaki balşka bir noktaya anında ışınlanmanızı sağlayacak. Işınlanmak için sadece yanında olmayan bir yere tıkla.") + +S("This orb lets you instantly move to a safe faraway location. Knowing the nature of this strange world, you doubt " + "that you will ever find the way back...\n\n" + "Your game will be saved if you quit the game while the Orb of Safety is still powered.\n\n" + "Technical note: as it is virtually impossible to return, this Orb recycles memory used for the world so far (even if you do not use it to save the game). ", + "Bu küre seni güvenli bir uzak yere ışınlar. Bu dünyanın garip yapısını düşününce " + "geri dönüp dönemeyeceğin belli değil...\n\n" + "Eğer Güvenlik Küresi hâlâ açıkken oyundan çıkarsan oyunun kaydedilecek.\n\n" + "Teknik not: geri dönmek aslında tamamen imkânsız olduğundan, bu Küre sadece şimdiye kadar bu dünya için kullanılan hafızayı kullanır. (onu ounu kaydetmek için kullanmasanız da.) ") + +S("This orb allows attacking Hedgehog Warriors directly, as well as stabbing other monsters.\n", + "Bu küre Kirpi Savaşçılara doğrudan saldırmaya ve diğer canavarları bıçaklamaya izin verir.\n") + +S("This flower brings fortune to the person who finds it.\n", + "Bu çiçek kendisini bulana şans getirir.\n") + +S("Ice Walls melt after some time has passed.", "Buz Duvarları biraz zaman geçince erirler.") + +S("A natural terrain feature of the Desert.", "Çölün içinde doğal bir kum oluşumu.") + +S("You can go inside the Magic Mirror, and produce some mirror images to help you.", + "Sihirli aynanın içine girerek sana yardım etmesi için bazı yansımalar üretebilirsin.") + +S( + "Tiny droplets of magical water. You see images of yourself inside them. " + "Go inside the cloud, to make these images help you.", + "Ufak sihirli su damlaları. Kendi görüntünü içlerinde görüyorsun. " + "Bu görüntülerin sana yardım etmesi için bulutun içine gir. ") + +S("A device that attracts sandworms and other enemies. You need to activate it.", + "Kumkurtlarını ve diğer düşmanları çağıracak bir aygıt. Sadece etkinleştirmen gerekiyor.") + +S("A heap of wood that can be used to start a fire. Everything is already here, you just need to touch it to fire it.", + "Ateş yakmaya uygun bir yığın odun. Her şey zaten burada, ateş için sadece dokunman yetecek.") + +S("An ancient grave.", "Antik bir mezar.") + +S("A fresh grave. Necromancers like those.", "Taze bir mezar. Ölüçağıranlar bunu sever.") + +S("A piece of architecture typical to R'Lyeh.", "R'Lyeh'e özgü bir mimari eser.") + +S("An impassable lake in Cocytus.", "Kokitos'ta, üzerinden geçilemeyen bir göl.") + +S("You can walk on it... but beware.", "Üzerinde yürüyebilirsin. Ama dikkatli ol!") + +S("It was a floor... until something walked on it.", "Burası bir zemin parçasıydı...ta ki bir şey üzerinden geçene kadar.") + +S( + "This land is a quick gateway to other lands. It is very easy to find other lands " + "from the Crossroads. Which means that you find monsters from most other lands here!\n\n" + "As long as you have found enough treasure in their native lands, you can " + "find magical items in the Crossroads. Mirror Land brings mirrors and clouds, " + "and other land types bring magical orbs.\n\n" + "A special treasure, Hyperstone, can be found on the Crossroads, but only " + "after you have found 10 of every other treasure.", + "Bu diyar diğer diyarlara kolay geçiş için var. Arayollardan başka diyarları bulması çok kolay. " + "Bu demektir ki, burada başka diyarlardan canavarlar bulman çok olası!\n\n" + "Eğer hazineleri kendi yerlerinde yeterince topladıysan, Arayollarda sihirli eşyalar bulabilirsin. " + "Ayanalar Diyarından yansımalar ve bulutlar, diğer diyarlardan sihirli küreler gelebilir.\n\n" + "Özel bir hazine, Aşkıntaş, sadece Arayollarda bulnabilir, ama öncesinde diğer her hazine çeşidinden 10'ar tane bulman gerekiyor.") + +S("A hot land, full of sand dunes, mysterious Spice, and huge and dangerous sand worms.", + "Kum tepeleri, gizemli Baharat ve devasa Kumkurtlarıyla dolu sıcak bir diyar.") + +S( + "A very cold land, full of ice walls. Your mere presence will cause these ice walls to " + "melt, even if you don't want it.", + "Buz duvarlarıyla dolu çok soğuk bir diyar. Sen istemesen de sadece varlığın bile duvarların erimesine sebep oluyor.") + +S("A land filled with huge ivy plants and dangerous animals.", + "Sarmaşık bitkileri ve tehlikeli hayvanlarla dolu bir diyar.") + +S("A strange land which contains mirrors and mirages, protected by Mirror Rangers.", + "Aynalar ve yansımalarla dolu garip bir diyar, ayna korucuları tarafından korunuyor.") + +S("All the monsters you kill are carried to this strange land, and buried. " + "Careless Rogues are also carried here...", + "Öldürdüğünüz bütün canavarlar buraya taşındı ve gömüldü. Dikkatsiz Seyyahlar da buraya taşındı...") + +S("An ancient sunken city which can be reached only when the stars are right.\n\n" + "You can find Temples of Cthulhu in R'Lyeh once you collect five Statues of Cthulhu.", + "Sadece yıldızlar burayı işaret ettiğinde ulaşılabilecek batık bir antik şehir.\n\n" + "Cthulhu'nun tapınaklarını 5 Cthulhu heykeli topladıktan sonra bulabilirsin.") + +S("A land filled with demons and molten sulphur. Abandon all hope ye who enter here!", + "Şeytanlarla ve erimiş sülfürle dolu bir diyar. Buraya giriyorsan tüm ümitlerini terket!") + +S("This frozen lake is a hellish version of the Icy Land. Now, your body heat melts the floor, not the walls.", + "Bu donmuş göl, Buz Diyarlarının korkunç bir versiyonu gibi. Şimdi, vücut ısın duvarları değil, yeri eritiyor.") + +S("A land where you cannot stop, because every piece of floor is extremely unstable. Only monsters who " + "can run forever are able to survive there, and only phoenix feathers are so light that they do not disturb " + "the floor.\n", + "Duramayacağınız bir diyar...Çünkü zeminin her noktası oldukça kırılgan. Sadece sonsuza kadar koşabilen canavarlar" + " burada yaşayabilirler ve anka telekleri öyle hafiftir ki, zemine zarar vermezler.") + +S("Affects looks and grammar", "Görüntüyü ve grameri etkiler") + +S("first joystick: movement threshold", "birinci oyun kolu: hareket eşiği") +S("first joystick: execute movement threshold", "birinci oyun kolu: hareket algılama eşiği") +S("second joystick: pan threshold", "ikinci oyun kolu: gezdirme hızı") +S("second joystick: panning speed", "ikinci oyun kolu: gezdirme hızı") +S("%The1 is frozen!", "%1 dondu!") +S("%The1 burns!", "%1 yandı!") +S("message flash time", "mesaj gösterme süresi") + +S("Euclidean mode", "Öklid modu") +S("Return to the hyperbolic world", "Hiperbolik Dünyaya geri dön") +S("Choose from the lands visited this game.", "Oyunda eriştiğin diyarlardan birini seç.") +S("Scores and achievements are not", "Başarımlar ve puanlar Öklid"); +S("saved in the Euclidean mode!", "modunda kaydedilmeyecek!"); + +S("Your total treasure has been recorded in the Google Leaderboards.", "Toplam hazinen Google Listelerine kaydedildi.") +S("You have improved your total high score on Google. Congratulations!", "Google'daki toplam yüksek puanını artırdın. Tebrikler!") +S("This has been recorded in the Google Leaderboards.", "Bu Google Listelerine kaydedildi.") +S("You have improved your '%1' high score on Google!", "Google'daki '%P1'puanını artırdın!") + +S("MOVE", "OYNAT") +S("BACK", "GERİ") +//S("DRAG", "SÜRÜKLE") +S("DRAG", "SRKLE") +S("INFO", "BİLGİ") +S("MENU", "MENÜ") +S("QUEST", "GÖREV") +S("HELP", "YARDIM") +S("NEW", "YENİ") +S("PLAY", "OYNA") +S("SHARE", "PAYLAŞ") +S("HyperRogue for Android", "Android için HyperRogue") +S("Cheats: ", "Hileler: ") +S("Score: ", "Puan: ") +S("Kills: ", "Leşler: ") +S("Retrieving scores from Google Leaderboards...", "Google listelerindeki puanlar yükleniyor...") +S("Scores retrieved.", "Puanlar yüklendi.") + +S("Ever wondered how some boardgame would look on the hyperbolic plane? " + "I wondered about Go, so I have created this feature. Now you can try yourself!\n" + "Enter = pick up an item (and score), space = clear an item\n" + "Other keys place orbs and terrain features of various kinds\n" + "In the periodic editor, press 0-4 to switch walls in different ways\n", + "Hiç bir oyunun hiperbolik düzlemde nasıl görüneceğini merak ettin mi? " + "Ben Go hakkında merak ettim ve bu özelliği geliştirdim. Sen de deneyebilirsin!\n" + "Enter = bir itemi al (ve puan kazan), space = bir itemi temizle\n" + "Diğer tuşlar küreler ve çeşitli arazi özellikleri eklemek için.\n") + +S("","") N("",GEN_N,"","","","") + +S("Periodic Editor", "Periyodik Editör") +// also translate this line: +// "In the periodic editor, press 0-4 to switch walls in different ways\n", +// "Periyodik editörde, duvarları farklı şekillerde seçmek için 0-4'e basın.\n" + +S("Collect 60 $$$ to access even more lands", "Daha da fazla diyara ulaşmak için 60 $$$ toplayın.") + +// Emerald Mine + +N("Emerald Mine", GEN_F, "Zümrüt Madeni", "Zümrüt Madenleri", "Zümrüt Madenini", "Zümrüt Madeninde") +N("Pikeman", GEN_M, "Mızraklı", "Mızraklılar", "Mızraklıyı", "Mızraklıyla") +N("Flail Guard", GEN_M, "Topuz Muhafızı", "Topuz Muhafızları", "Topuz Muhafızını", "Topuz Muhafazıyla") +N("Miner", GEN_M, "Madenci", "Madenciler", "Madenciyi", "Madenciyle") +N("Emerald", GEN_O, "Zümrüt", "Zümrütler", "Zümrütü", "Zümrütle") + +Orb("the Mind", "Psychiki") + +S( + "Evil people are mining for emeralds in this living cave. " + "It does not grow naturally, but it is dug out in a regular " + "pattern, which is optimal according to the evil engineers.", + "Kötü insanlar bu mağarada zümrüt çıkarıyor. Doğal yollarla çıkmıyor, şeytani mühendislerin işine gelecek şekilde düzenli bir şemayla çıkarılıyor.") + +S( + "Miners have special tools for dealing with the Living Cave. " + "When they die, these tools activate, destroying the living cave " + "around them.", + "Madenciler Yaşayan Mağarayla baş etmek için özel gereçlere sahipler. Öldüklerinde, bu gereçler aktifleşiyor ve etraflarındaki Yaşayan Mağarayı yok ediyor.") + +S( + "When Pikemen move, they attack all cells which are now adjacent to them. " + "Luckily, they can be killed in the same way.\n\n" + "They never move if this would attack their friends.", + "Mızraklılar hareket ettiğinde değdikleri tüm hücrelere saldırırlar. Çok şükür aynı şekilde öldürülebiliyorlar da. Arkadaşlarına hasar vereceklerse hareket etmiyorlar.") + +S( + "This guard of the Emerald Mine is wielding a huge flail. " + "You cannot attack him directly, as the flail would still hit you then. " + "Luckily, you have learned a trick: if you step away from him, " + "he will hit himself with the flail!", + + "Zümrüt Madeninin bu muhafızı kocaman bır topuz tutuyor. Ona doğrudan saldıramazsın, çünkü topuz sana yine de vurur. Çok şükür bir hile öğrendin: Eğer geriye doğru bir adım atarsan, muhafız topuzuyla kendisine vuracak!") + +S("A precious green gem from the Emerald Mines.", "Zümrüt Madenlerinden eğerli yeşil bir mücevher.") + +S("%The1 pierces %the2!", "%1 %a2 delip geçiyor!") + +S("Make him hit himself by walking away from him.", + "Ondan uzaklaşarak kendisine vurmasını sağla.") + +S("This orb allows you to instantly kill a non-adjacent enemy by clicking it. " + "Each use drains 30 charges.", + "Bu küre yakında olmayan herhangi bir düşmana tıklayarak onu öldürebilmene izin verir. Her kullanım 30 şarj götürür.") + +S("%The1 is immune to mental blasts!", "%1 zihin patlamasından etkilenmez!") +S("You kill %the1 with a mental blast!", "%a2 zihin patlamasıyla öldürdün!") + +// Vineyard + +N("Vineyard", GEN_F, "Şaraplık", "Şaraplıklar", "Şaraplığı", "Şaraplıkta") +N("Vine Beast", GEN_M, "Şarap Canavarı", "Şarap Canavarları", "Şarap Canavarını", "Şarap Canavarıyla") +N("Vine Spirit", GEN_M, "Şarap Özü", "Şarap Özleri", "Şarap Özünü", "Şarap Özüyle") +N("vine", GEN_F, "şarap", "şaraplar", "şarabı", "şarapla") +N("partial fire", GEN_M, "kısmî ateş", "kısmî ateşler", "kısmî ateşi", "kısmî ateşle") +N("Wine", GEN_N, "Şarap", "Şaraplar", "Şarabı", "Şarapla") + +S( "This cell is partially on fire.", "Bu hücre kısmen alevler içinde.") + +S( + "The Vineyard is filled with vines. A very dense pattern of straight lines here...\n\n" + "Vine Beasts and Vine Spirits change vine cells to grass, and vice versa.", + "Şaraplık şaraplarla dolu. Burada çok sık düz çizgiler var ...\n\n" + "şŞarap Canavarları ve Şarap Özleri şarap hücrelerini çimene ve tam tersine çevirir.") + +S("A vine is growing here... but only on a half of the cell. How is that even possible?!" + "Most monsters cannot move from this cell to the cell containing the other half. " + "Vine spirits can move only to the adjacent cells which are also adjacent to the " + "other half.", + "Burada şarap oluşuyor... ama sadece hücrenin yarısında. Bu nasıl mümkün olabilir?! Çoğu canavar bu hücreden diğer yarıyı içeren hücreye hareket edemez. Şarap özleri sadece diğer yarıya da bitişik olan hücrelere gidebilir.") + +S( + "A beast made of vines!\n\n" + "Vine Beasts turn into vines when they die.", + "Şaraptan yaratılmış bir canavar!\n\n" + "Şarap Canavarı öldüğünde şaraba dönüşür.") + +S( "A spirit living in the vines!\n\n" + "Vine Spirits destroy the vines when they die.", + "Şarabın içinde yaşayan bir ruh!\n\n" + "Şarap ruhları öldüklerinde etraflarındaki şarabı yok eder.") + +S("Wine grown under hyperbolic sun would be extremely prized in your home location.", + "Hiperbolik güneşin altında oluşan şarap geldiğin yerde epey değerli olsa gerek.") + +S("This orb allows one to pass through all kinds of walls and chasms.", + "Bu küre her türlü duvarların ve çatlakların içinden geçmene izin verir.") + +S("You cannot attack through the Vine!", + "Şarabın içinden saldıramazsın!") + +Orb("Aether", "Eter") + +// Dead Caves + +N("Dead Cave", GEN_F, "Ölü Mağara", "Ölü Mağaralar", "Ölü Mağarayı", "Ölü Mağarada") +N("Dark Troll", GEN_M, "Kara Trol", "Kara Troller", "Kara Trolü", "Kara Trolle") +N("Earth Elemental", GEN_M, "Toprakadam", "Toprakadamlar", "Toprakadamı", "Toprakadamla") +N("dead wall", GEN_F, "ölü duvar", "ölü duvarlar", "ölü duvarı", "ölü duvarda") +N("dead floor", GEN_F, "ölü zemin", "ölü zeminler", "ölü zemini", "ölü zeminde") +N("rubble", GEN_O, "gruz", "gruzy", "gruz", "gruzem") +N("Silver", GEN_N, "Gümüş", "Gümüşler", "Gümüşü", "Gümüşle") + +S("A precious metal from the Dead Caves.", "Ölü mağaralardan çıkan değerli bir metal.") + +S( "A Troll without the power of Life.", "Hayat gücünden mahrum bir trol.") + +S( + "A rare unliving construct from the Dead Caves. " + "It instantly destroys cave walls next to its path, and also leaves " + "an impassable wall behind it. You suppose that this impassable wall helps it to " + "escape from some threats. You hope you won't meet these threats...", + + "Ölü Mağaralardan cansız bir mekanizma. Yoluna çıkan tüm mağara duvarlarını yıkar ve arkasında geçilemeyen bir duvar bırakır." + "Bu duvarları birtakım tehditlerden kullanabileceğini düşünüyorsun. Aynı zamanda bu tehditlerle hiç karşılaşmayacağını da umuyorsun..") + +S("%The1 punches %the2!", "%1 %a2 yumrukladı!") +S("%The1 is destroyed by the forces of Life!", "Yaşam güçleri %a1 yok etti!") +S( "Somehow, this cave has not received the spark of Life yet.", + "Nasılsa bu mağaraya yaşamın ışığı hiç uğramamış.") + +// Hive +N("Hive", GEN_N, "Kovan", "Kovanlar", "Kovanı", "Kovanda") +N("Red Hyperbug", GEN_M, "Kırmızı Aşkınböcek", "Kırmızı Aşkınböcekler", "Kırmızı Aşkınböceği", "Kırmızı Aşkınböcekle") +N("Green Hyperbug", GEN_M, "Yeşil Aşkınböcek", "Yeşil Aşkınböcekler", "Yeşil Aşkınböceği", "Yeşil Aşkınböcekle") +N("Blue Hyperbug", GEN_M, "Mavi Aşkınböcek", "Mavi Aşkınböcekler", "Mavi Aşkınböceği", "Mavi Aşkınböcekle") +N("Royal Jelly", GEN_N, "Müthiş Jöle", "Müthiş Jöleler", "Müthiş Jöleyi", "Müthiş Jöleyle") +N("weird rock", GEN_N, "garip kaya", "garip kayalar", "garip kayayı", "garip kayayla") + +Orb("Invisibility", "Görünmezlik") + +S("A weirdly colored rock. Hyperentomologists claim that the " + "Hyperbug armies use these rocks to navigate back home after a victorious battle.", + "Garip renkli bir kaya. Aşkınböcekbilimcilere göre aşkın böcek orduları bu kayaları zaferlerinden sonra evlerini bulmak için kullanıyorlar.") + +S("%The1 fights with %the2!", "%1 %a2 savaşıyor!") + +S("The Hive is filled with Hyperbugs. They are huge insects which look a bit like " + "ants, a bit like bees, and a bit like roaches. " + "They live in circular nests, and an army of Hyperbugs will attack any intruder, " + "including you and enemy Hyperbugs. Will you manage to get to the " + "heart of such a nest, and get the precious Royal Jelly?", + "Kovan aşkın böceklerle dolu. Aşkınböcekler biraz arıya biraz karıncaya biraz da hamamböceğine benzeyen kocaman böcekler. Dairesel kovanlarda yaşıyorlar ve yaklaşan düşman aşkınböceklerine" + "ve sana saldıracaklardır. Kovanın merkezine ulaşıp Müthiş Jöleyi ele geçirebilecek misin ?") + +S("This is what Hyperbug Queens eat. Very tasty and healthy.", + "Bu Aşkınböcek Kraliçelerinin yediği şey. Çok lezzetli ve sağlıklı.") + +S("When you have this Orb, most monsters won't see you, unless " + "you are standing still, attacking, or picking up items.", + "Bu küren varsa çoğu canavar seni beklemediğin, saldırmadığın yahut yerden bir şey almadığın sürece görmez.") + +Orb("Earth", "Toprak") + +S("This orb lets you go through living walls. It also has powers in some of the other lands.", + "Bu küre yaşayan duvarların içinden geçebilmeni sağlar. Bazı başka diyarlarda da başka güçleri olabilir.") + +// Land of Power + +N("Land of Power", GEN_F, "Güç Diyarı", "Güç Diyarları", "Güç Diyarını", "Güç Diyarında") +N("Witch Apprentice", GEN_F, "Cadı Kalfası", "Cadı Kalfaları", "Cadı Kalfasını", "Cadı Kalfasıyla") +N("Speed Witch", GEN_F, "Hız Cadısı", "Hız Cadıları", "Hız Cadısını", "Hız Cadısıyla") +N("Flash Witch", GEN_F, "Işık Cadısı", "Işık Cadıları", "Işık Cadısını", "Işık Cadısıyla") +N("Fire Witch", GEN_F, "Ateş Cadısı", "Ateş Cadıları", "Ateş Cadısını", "Ateş Cadısıyla") +N("Aether Witch", GEN_F, "Eter Cadısı", "Eter Cadıları", "Eter Cadısını", "Eter Cadısıyla") +N("Winter Witch", GEN_F, "Kış Cadısı", "Kış Cadıları", "Kış Cadısını", "Kış Cadısıyla") +N("Evil Golem", GEN_M, "Şeytani Golem", "Şeytani Golemler", "Şeytani Golemi", "Şeytani Golemle") +N("Powerstone", GEN_M, "Güç Taşı", "Güç Taşları", "Güç Taşını", "Güç Taşıyla") +N("crystal cabinet", GEN_F, "Kristal Kabin", "Kristal Kabinler", "Kristal Kabini", "Kristal Kabinle") + +S("When you have this Orb, you will leave a trail of fire behind you.", + "Bu Küreye sahip olduğunda arkanda bir ateşten yol bırakırsın.") + +S( + "A Witch without any special powers. But watch out! She will " + "pick up any basic Orbs on her path, and use their powers.", + "Herhangi bir gücü olamyan bir Cadı. Ama dikkat! Yolunun üzerindeki herhangi bir Küreyi alıp güçlerini kullanabilir.") + +S( "A Witch with a Speed spell. She moves twice as fast as you. Unless you " + "have an Orb of Speed too, of course!", + "Hız büyüsü olan bir Cadı. Senden iki kat hızlı hareket eder. Tabi senin de bir Hız Küren yoksa!") + +S( "A Witch with a Fire spell. She will leave a trail of fire behind her.", + "Ateş büyüsü olan bir Cadı. Arkasında ateşten bir yol bırakır.") + +S( "A Witch with a Winter spell. She is able to move through fire.", + "Kış büyüsü olan bir cadı. Ateşin içinde yürüyebilir.") + +S( "A Witch with an Aether spell. She is able to move through fire and walls.", + "Eter büyüsü olan bir cadı. Duvarların ve ateşin içinden geçebilir.") + +S( "Somebody has summoned these evil constructs with a magical process.", + "Birisi büyüyle işleyen bu mekanizmaları harekete geçirmiş.") + +S( "The Land of Power is filled with everburning fire, magical Orbs, and guarded by " + "witches and golems. There are basic orbs lying everywhere, and more prized ones " + "are kept in crystal cabinets.\n\n" + "Witches are allowed to use all the powers of the " + "basic orbs against intruders. These powers never expire, but a Witch " + "can use only one power at a time (not counting Orbs of Life).\n\n" + "Witches and Golems don't pursue you into other Lands. Also, most Orb powers" + "are drained when you leave the Land of Power.", + "Güç Diyarı sönmeyen ateşle, büyülü Kürelerle dolu ve cadılar ve golemler ile korunuyor. Her yerde temel Küreler var ve daha değerliler de kristal kabinlerde korunuyor. \n\n" + "Cadılar bu kürelerin gücünü olası işgalcilere karşı kullanabilirler. Bu güçlerin süresi bitmez ama Yaşam Küresi hariç cadılar aynı anda sadece birini kullanabilir. \n\n" + "Cadılar ve Golemler seni diğer diyarlara kadar takip etmezler. Ayrıca çoğu kürenin gücü Güç Diyarını terkettiğinde biter.") + +S( + "Witches use these crystal cabinets to protect Powerstones, as well as the more " + "expensive Orbs. They are partially protected from thieves: they are too strong " + "to be smashed by conventional attacks, and if you try to steal the item " + "using an Orb of Aether, your Aether power will be completely drained.", + "Bu kabinleri Cadılar Güçtaşlarını ve değerli Küreleri korumak için kullanıyorlar. Hırsızlara karşı kısmen korumalıdır, bildik saldırılarla kırılmak için fazlasıyla serttir ve eğer içindeki eşyayı Eter Küresi kullanarak çalmaya çalışırsan kürenin gücü bitecektir.") + +S( + "A Stone from the Land of Power. You are not sure what it is exactly, but " + "as the Powerstones are kept in crystal cabinets, they are surely valuable.", + "Güç Diyarından bir taş. Ne olduğuna tam olarak emin değilsin, ama bu taşlar kristal kabinlerde saklandığına göre çok değerli olmalılar.") + +Orb("Fire", "Ateş") + +// achievements: + +// x "Head Witch", "Have 10 Orbs active at the same time." +// "Enemy Number One", "Have an army of 1000 hyperbugs pursue you." +// x "Lifebringer", "Brought Life into the Dead Caves." +// "Wall Gardener", "Make a living wall grow outside of a cavernous region." +// x "Master Swordsman", "Defeat a Hedgehog Warrior, a Pikeman, and a Flail Guard at the same time." +// x "Master of Melee", "Defeat five monsters in melee at the same time." + +// for collection achievements: +// provide the required cases for descriptions: +// Spice, Royal Jelly, Silver, Powerstone, and Wine +// achievement names: +// Master of the Hive, Master of Power, Master of Vineyard, Master of Dead Caves, Master of the Mine +// "Hyperbug", "Hyperbug Warrior", "Hyperbug Queen", + +// for the store description: + +// (currently, five more lands are included!) + +// lines forgotten previously + +S("Your Aether power has expired! RUN!", "Eter gücünün süresi bitti! KAÇ!") + +S("%The1 tricks %the2.", "%1 %a2 kandırdı.") +S("You trick %the1.", "%a1 kandırdın.") + +S( "A Witch with a Flash spell. Very dangerous!\n\nLuckily, she never uses the spell if it " + "would kill her friends. She could destroy an Evil Golem, though.", + "Işık büyüsü olan bir cadı. Çok tehlikeli!\n\n Çok şükür, büyüsünü büyüsü arkadaşlarını da öldürecekse hiç kullanmaz. Ama Şeytani Golemi de umursayacak değil tabi.") + +S("Your Aether powers are drained by %the1!", "Güçlerin %1 tarafından tüketiliyor!") +S("As you leave, your powers are drained!", "Ayrılırken, tüm güçlerinin tükendiğini farkettin!") +S("%The1 picks up %the2!", "%1 %a2 kaldırdı!") // currently only Witches, so only female form + +S("You can right click any element to get more information about it.\n\n", + + "Herhangi bir şeye sağ tıklayarak hakkında daha çok bilgiye ulaşabilirsin.\n\n") + +// S("The Hyperbugs are fighting!", "Aşkın böcekler savaşıyor!") +S("The Hyperbugs are fighting!", "Aşkınböcekler savaşıyor!") + +S("Dead floor, with some rubble.", "Ölü zemin, üstünde taş parçaları var.") +S("Cheat-changed the display.", "Cheat-changed the display.") + +S("skin color", "deri rengi") +S("weapon color", "silah rengi") +S("hair color", "saç rengi") +S("dress color", "kıyafet rengi") +S("Shift=random, Ctrl=mix", "Shift=rastgele, Ctrl=karışık") + +S("openGL & antialiasing mode", "openGL & antialiasing") + +S("Date: %1 time: %2 s ", "Tarih: %1 zaman: %2 s ") +S("distance: %1\n", "uzaklık: %1\n") + +// Camelot + +N("Camelot", GEN_O, "Kamelot", "Kamelotlar", "Kamelotu", "Kamelotta") +N("wall of Camelot", GEN_F, "Kamelot Duvarı", "Kamelot Duvarları", "Kamelot Duvarını", "Kamelot Duvarıyla") +N("moat of Camelot", GEN_F, "Kamelot hendeği", "Kamelot hendekleri", "Kamelot hendeğini", "Kamelot hendeğiyle") +N("Round Table", GEN_O, "Yuvarlak Masa", "yuvarlak Masalar", "Yuvarlak Masayı", "Yuvarlak Masayla") +N("Knight", GEN_M, "Şövalye", "Şövalyeler", "Şövalyeyi", "Şövalyeyle") +N("Holy Grail", GEN_O, "Kutsal Kâse", "Kutsal Kâseler", "Kutsal Kâseyi", "Kutsal Kâseyle") + +S( + "The Knights of the Round Table are the greatest warriors of these lands. " + "They are not very inventive with names though, as they call each of their " + "castles Camelot. " + "You are probably worth of joining them, but they will surely give you " + "some quest to prove yourself...\n\n" + "Each castle contains a single treasure, the Holy Grail, in the center. " + "The radius of the Round Table is usually 28, but after you find a Holy Grail " + "successfully, each new castle (and each Round Table) you find will be bigger.", + + "Yuvarlak masa Şövalyeleri bu toprakların en müthiş savaşçıları. " + "Kalelerine Kamelot demelerine bakılırsa, isimlerle araları pek iyi değil herhalde. " + "Aralarına katılmaya büyük ihtimalle layıksın, ama yine de sana kendini kanıtlamak için bir görev verecekler... \n\n " + "Her kale merkezinde tek bir hazineyi, Kutsal Kâseyi barındırıyor. " + "Yuvarlak masanın çapı genelde 28'dir, ama Kutsal Kâseyi bir kez bulduğunda, karşılaştığın her yeni kale (ve her yuvarlak masa) eskisinden daha büyük olacak.") + +S("It would be impolite to land on the table!", + "Masaya çıkmak çok yakışıksız olur!") +S("You jump over the table!", "Masanın üstüne çıktın!") +S("That was not a challenge. Find a larger castle!", + "Bu seni heyecanlandırmadı bile. Daha büyük bir kale bul!") +S("The Knights congratulate you on your success!", + "Şövalyeler başarın için seni tebrik ediyor!") +S("The Knights laugh at your failure!", + "Şövalyeler hezimetine katıla katıla gülüyor!") +S("The Knights stare at you!", "Şövalyeler sana dik dik bakıyor!") +S("Come on, this is too easy... find a bigger castle!", + "Pöfff, çok kolaydı... daha büyük bir kale bul!") +S("The Knights wish you luck!", "Şövalyeler sana şans diliyor!") + +S("\"I would like to congratulate you again!\"", "\"Seni tekrar tebrik etmek isterim!\"") +S("\"Find the Holy Grail to become one of us!\"", "\"Bizden biri olmak için Kutsal Kâseyi bul!\"") +S("\"The Holy Grail is in the center of the Round Table.\"", "\"Kutsal Kâse Yuvarlak Masanın merkezinde.\"") +S("\"I enjoy watching the hyperbug battles.\"", "\"Aşkınböcek savaşlarını izlemek hoşuma gidiyor.\"") +S("\"Have you visited a temple in R'Lyeh?\"", "\"R'Lyeh'teki tapınağı ziyaret ettin mi?\"") +S("\"Nice castle, eh?\"", "\"Kalemiz güzel, değil mi?\"") + +// Temple + +N("Temple of Cthulhu", GEN_F, "Cthulhu'nun Tapınağı", "Cthulhu'nun Tapınakları", "Cthulhu'nun Tapınağını", "Cthulhu'nun Tapınağında") +N("big statue of Cthulhu", GEN_O, "Cthulhu'nun Putu", "Cthulhu'nun Putları", "Cthulhu'nun Putunu", "Cthulhu'nun Putuyla") +N("Grimoire", GEN_F, "Kara Kitap", "Kara Kitaplar", "Kara Kitabı", "Kara Kitapla") +N("Cult Leader", GEN_M, "Kült Lideri", "Kült Liderleri", "Kült Liderini", "Kült Lideriyle") + +S("The temple of Cthulhu consists of many concentric circles of columns. " + "You will surely encounter many Cultists there, who believe that a pilgrimage " + "to the inner circles will bring them closer to Cthulhu himself, and Grimoires " + "which surely contain many interesting secrets.\n\n" + "The circles in the temple of Cthulhu are actually horocycles. They are " + "infinite, and there is an infinite number of them.", + + "Cthulhu tapınağı çok sayıda eş merkezli dairesel sütunlardan oluşur. " + "Burada iç dairelere yapılan bir haccın kendilerini Cthulhu'ya daha çok yaklaştırdığına inanan bir çok Müritle ve çok ilginç sırlar içeren Kara Kitaplarla karşılaşacaksın. \n\n" + "Cthulhu Tapınağının merkezindeki daireler aslında horoçemberler. Onlar sonsuz ve onlardan sonsuz tane var." + ) + +S("The Grimoires contain many secrets of the Great Old Ones. " + "Each new inner circle in the Temple of Cthulhu contains new Grimoires, with new secrets. " + "You hope to read them when you return home, and to learn many things. " + "The knowledge is valuable to you, but it is rather pointless to try to get " + "several copies of the same Grimoire...", + "Kara Kitaplar Eski Yücelere dair pek çok sır içerir. Cthulhu Tapınağındaki her iç daire yeni sırlar içeren yeni Kara Kitaplar içerir." +"Eve geri döndüğünde bunları okuyup pek çok şey öğrenmeyi umuyorsun. Bilgi senin için önemli, bu yüzden aynı Kara Kitaptan birden fazla almak çok anlamsız." + ) + +S("These statues of Cthulhu are too large to carry, and they don't look too " + "valuable anyway. Most monsters will never go through them... they probably have " + "their reasons. But you can go! When you move into the cell containing " + "a statue, you push the statue to the cell you left.\n", + + "Cthulhu putları taşımak için fazla büyük, zaten çok değerli de gözükmüyorlar. Canavarların çoğu onların içinden geçmiyor, bunun bir sebebi olmalı. " +"Ama sen bunların içinden geçebilirsin! Putun olduğu hücreye girdiğinde putu terkettiğin hücreye itersin. \n" + ) + +S("These Cultists can push the statues, just like you.", + "Bu Müritler putları tıpkı senin gibi itebilir.") + +S("You already have this Grimoire! Seek new tomes in the inner circles.", + "Bu Kara Kitaptan elinde zaten var! Yeni ciltleri iç dairelerde ara.") + +S("You push %the1 behind you!", "%a1 arkana ittin.") + +// More texts + +S("Your total kills", "Toplam leşler") + +S( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count.", + + "Çoğu diyarda, orada yaşayan canavarları öldürmen daha çok hazineyle karşılaşmanı sağlar. Ayrıca 100 leş Mezarlık ve Kovana girmen için bir önkoşuldur. \n\n" +"Dost yaratıklar ve canavarların parçaları (Sarmaşık gibi) litede gözükürt, ama toplam leşlere dahil edilmez.") + +S("There must be some temples of Cthulhu in R'Lyeh...", + "R'Lyeh'te Cthulhu'ya adanmış bazı tapınaklar olmalı...") + +S("You overheard Hedgehog Warriors talking about emeralds...", + "Kirpi Savaşçıların zümrütler hakkında konuştuğunu duydun...") + +S("You overhear miners talking about a castle...", + "Madencilerin bir kale hakkında konuştuğunu duydun...") + +S("A castle in the Crossroads...", "Arayollarda bir Kale...") + +// S("TRANSLATIONWARNING", "Uyarı: Türkçe çeviri henüz Sürüm 6.2' daki yeni özellikleri kapsamıyor.") + +S("TRANSLATIONWARNING", "") + +S("You have to escape first!", "Önce kaçman gerekiyor!"); +S("There is not enough space!", "Yeterince yer yok!"); + +S("Customize character", "Karakteri düzenle.") +S("gender", "cinsiyet") + +S("Congratulations! You have found the Holy Grail!", + "Tebrikler! Kutsal Kâseyi buldun!") + +Orb("the Dragon", "Ejderha") + + + +S("This Orb allows you to throw fire, just like the Fire Cultists.\n\n" + "Each fire drains 5 charges. You are not allowed to throw fire into adjacent cells.", +//"Bu Küre tıpkı Ateş Müritleri gibi ateş atabilmeni sağlar." + "Bu Küre tıpkı Ateş Müritleri gibi ateş atabilmeni sağlar.\n\nHer ateş 5 şarj tüketir, bitişik hücrelere ateş atamazsın." + ) + +S("You throw fire!", "Ateş attın!") + +Orb("Trickery", "Kandırma") + +N("Illusion", GEN_F, "İlüzyon", "İlüzyonlar", "İlüzyonu", "İlüzyonla") + +S("This Orb allows you to create illusions of yourself. Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.\n\n" + "Each illusion takes 5 charges to create, and one extra charge " + "per turn. You can also click your illusion to take it away, restoring 4 charges.\n\n" + "If you have both Orb of Teleport and Orb of Trickery, Illusion is cast " + "first -- you can then teleport on your Illusion to switch places with it.", + "Bu Küre kendinin ilüzyonlarını çıkarmanı sağlar. İlüzyonlar tıpkı sen, Gümleyenler ve dostların gibi pek çok canavar tarafından saldırıya uğrayabilir.\n\n" + "Her ilüzyonu çıkarması 5 şarj ve her ek tur bir şarj tüketir. İlüzyona tıklayarak onu yok edip, 4 şarjını geri alabilirsin. \n\n" + "Aynı anda hem Kandırma hem Işınlanma Küren varsa, önce İlüzyon uygulanır, sonra istersen ilüzyonuna tıklayarak onla yer değiştirebilirsin. ") + +S("You create an Illusion!", "Bir İlüzyon ürettin!") + +S("You take the Illusion away.", "İllüzyonu yok ettin.") + +#undef Orb + +S("Cannot teleport on a monster!", "Bir canavarın üzerine ışınlanamazsın!") +S("Cannot teleport on an item!", "Bir eşyanın üzerine ışınlanamazsın!") +S("Cannot teleport here!", "Buraya ışınlanamazsın!") +//S("You cannot teleport that far away!", "O kadar uzağa ışınlanamazsın!") + +S("You cannot target that far away!", "O kadar uzağı hedefleyemezsin.") +S("You cannot target that close!", "O kadar yakını hedefleyemezsin!") +S("Cannot cast illusion on an item!", "Bir eşyanın üzerinde ilüzyon oluşturamazsın!") +S("Cannot cast illusion here!", "Burada ilüzyon oluşturamazsın!") +S("Cannot cast illusion on a monster!", "Bir canavarın üzerinde ilüzyon oluşturamazsın!") +S("Cannot throw fire there!", "Oraya ateş atamazsın!") + +S("Illusions are targetted " + "by most monsters, just like yourself, Thumpers, and your friends.", + "İlüzyonlar tıpkı sen, Gümleyenler ve dostların gibi pek çok canavar tarafından saldırıya uğrayabilir.") + +S("or ESC to see how it ended", "veya nasıl bittiğini görmek için ESC'ye bas") +S("high contrast", "yüksek kontrast") +S("draw the heptagons darker", "yedigenleri daha koyu çiz"); +S("targetting ranged Orbs Shift+click only", + "menzilli küreler için sadece Shift+sol tık") +S("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.", + "Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, vb.") +S("also hold Alt during the game to toggle high contrast", + + "ayrıca oyun sırasında Alt'a basılı tutarak yüksek kontrastı açıp kapatabilirsin.") + diff --git a/language.cpp b/language.cpp new file mode 100644 index 00000000..2ebf8d44 --- /dev/null +++ b/language.cpp @@ -0,0 +1,249 @@ +// #define CHECKTRANS + +#define NUMLAN 5 + +#define GEN_M 0 +#define GEN_F 1 +#define GEN_N 2 +#define GEN_O 3 + +struct stringpar { + string v; + stringpar(string s) : v(s) { } + stringpar(const char* s) : v(s) { } + stringpar(eMonster m) { v= minf[m].name; } + stringpar(eLand l) { v= linf[l].name; } + stringpar(eWall w) { v= winf[w].name; } + stringpar(eItem i) { v= iinf[i].name; } + }; + +void rep(string& pattern, string what, string to) { + size_t at = pattern.find(what); + if(at != string::npos) + pattern = pattern.replace(at, what.size(), to); + } + +typedef unsigned hashcode; + +// a quick hack to make this unambiguous on Android +#define hash my_hash + +struct sentence { + hashcode hash; + const char* xlat[NUMLAN-1]; + }; + +struct noun { + int genus; + const char *nom, *nomp, *acc, *abl; + }; + +struct fullnoun { + hashcode hash; + int english_grammar_flags; + noun n[NUMLAN-1]; + }; + +#include "language-data.cpp" + +hashcode hash(const string& s) { + hashcode r = 0; + for(int i=0; i const T* findInHashTableS(string s, const T *table, int size) { + int b = 0, e = size; + hashcode h = hash(s); + while(b!=e) { + int m = (b+e)>>1; + // printf("b=%d e=%d m=%d h=%x s=%x\n", b, e, m, table[m].hash, h); + if(table[m].hash >= h) e = m; + else b = m+1; + } + if(e != size && table[e].hash == h) + return &table[e]; + return NULL; + } + +#define findInHashTable(s,t) findInHashTableS(s, t, sizeof(t) / sizeof(t[0])) + +string choose3(int g, string a, string b, string c) { + if(g == GEN_M || g == GEN_O) return a; + if(g == GEN_F) return b; + if(g == GEN_N) return c; + return "unknown genus"; + } + +string choose4(int g, string a, string b, string c, string d) { + if(g == GEN_M) return a; + if(g == GEN_F) return b; + if(g == GEN_N) return c; + if(g == GEN_O) return d; + return "unknown genus"; + } + +int playergender(); +int lang(); + +void basicrep(string& x) { + + const sentence *s = findInHashTable(x, all_sentences); + if(!s) { + printf("WARNING: no translations for '%s'\n", x.c_str()); + } + + int l = lang(); + if(l) { + const sentence *s = findInHashTable(x, all_sentences); + if(s) x = s->xlat[l-1]; + } + + if(l == 1) { + rep(x, "%łeś0", choose3(playergender(), "łeś", "łaś", "łoś")); + rep(x, "%ąłeś0", choose3(playergender(), "ąłeś", "ęłaś", "ęłoś")); + rep(x, "%ógł0", choose3(playergender(), "ógł", "ogła", "ogło")); + } + + if(l == 3) { + rep(x, "%l0", choose3(playergender(), "l", "la", "lo")); + rep(x, "%d0", choose3(playergender(), "", "a", "o")); + } + } + +void parrep(string& x, string w, stringpar p) { + int l = lang(); + const fullnoun *N = findInHashTable(p.v, all_nouns); + if(l == 0) { + // proper names (R'Lyeh) + if(N && (N->english_grammar_flags & 1)) { + rep(x,"%"+w,p.v); + rep(x,"%the"+w, p.v); + rep(x,"%The"+w, p.v); + } + else { + rep(x,"%"+w,p.v); + rep(x,"%the"+w, "the " + p.v); + rep(x,"%The"+w, "The " + p.v); + } + // plural names (Crossroads) + if(N && (N->english_grammar_flags & 2)) + rep(x,"%s"+w, ""); + else + rep(x,"%s"+w, "s"); + return; + } + if(l == 1) { + if(N) { + rep(x, "%"+w, N->n[0].nom); + rep(x, "%P"+w, N->n[0].nomp); + rep(x, "%a"+w, N->n[0].acc); + rep(x, "%abl"+w, N->n[0].abl); + rep(x, "%ł"+w, choose3(N->n[0].genus, "ł", "ł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")); + } + else { + rep(x,"%"+w, p.v); + rep(x, "%P"+w, p.v); + rep(x, "%a"+w, p.v); + rep(x, "%abl"+w, p.v); + rep(x, "%ł"+w, choose3(0, "ł", "ła", "ło")); + } + } + if(lang() == 2) { + if(N) { + rep(x, "%"+w, N->n[1].nom); + rep(x, "%P"+w, N->n[1].nomp); + rep(x, "%a"+w, N->n[1].acc); + rep(x, "%abl"+w, N->n[1].abl); + } + else { + rep(x,"%"+w,p.v); + rep(x, "%P"+w, p.v); + rep(x, "%a"+w, p.v); + rep(x, "%abl"+w, p.v); + } + } + if(lang() == 3) { + if(N) { + rep(x, "%"+w, N->n[2].nom); + rep(x, "%P"+w, N->n[2].nomp); + rep(x, "%a"+w, N->n[2].acc); + rep(x, "%abl"+w, N->n[2].abl); + rep(x, "%ý"+w, choose3(N->n[2].genus, "ý", "á", "é")); + rep(x, "%l"+w, choose3(N->n[2].genus, "l", "la", "lo")); + rep(x, "%el"+w, choose3(N->n[2].genus, "el", "la", "lo")); + rep(x, "%ůj"+w, choose4(N->n[2].genus, "ého", "ou", "é", "ůj")); + rep(x, "%ým"+w, choose3(N->n[2].genus, "ým", "ou", "ým")); + if(p.v == "Mirror Image") + rep(x, "%s"+w, "se"); + if(p.v == "Mirage") + rep(x, "%s"+w, "s"); + } + else { + rep(x,"%"+w,p.v); + rep(x, "%P"+w, p.v); + rep(x, "%a"+w, p.v); + rep(x, "%abl"+w, p.v); + } + } + if(lang() == 4) { + if(N) { + rep(x, "%"+w, N->n[3].nom); + rep(x, "%P"+w, N->n[3].nomp); + rep(x, "%a"+w, N->n[3].acc); + rep(x, "%abl"+w, N->n[3].abl); + rep(x, "%E"+w, choose3(N->n[3].genus, "", "а", "о")); + rep(x, "%A"+w, choose3(N->n[3].genus, "ый", "ая", "ое")); + } + else { + rep(x,"%"+w,p.v); + rep(x, "%P"+w, p.v); + rep(x, "%a"+w, p.v); + rep(x, "%abl"+w, p.v); + } + } + } + +void postrep(string& s) { + } + +string XLAT(string x) { + basicrep(x); + postrep(x); + return x; + } +string XLAT(string x, stringpar p1) { + basicrep(x); + parrep(x,"1",p1.v); + postrep(x); + return x; + } +string XLAT(string x, stringpar p1, stringpar p2) { + basicrep(x); + parrep(x,"1",p1.v); + parrep(x,"2",p2.v); + postrep(x); + return x; + } + +string XLATN(string x) { + if(lang()) { + const fullnoun *N = findInHashTable(x, all_nouns); + if(N) return N->n[lang()-1].nomp; + } + return x; + } + +string XLAT1(string x) { + if(lang()) { + const fullnoun *N = findInHashTable(x, all_nouns); + if(N) return N->n[lang()-1].nom; + } + return x; + } + diff --git a/libogg-0.dll b/libogg-0.dll new file mode 100644 index 00000000..f538db18 Binary files /dev/null and b/libogg-0.dll differ diff --git a/libvorbis-0.dll b/libvorbis-0.dll new file mode 100644 index 00000000..620c485d Binary files /dev/null and b/libvorbis-0.dll differ diff --git a/libvorbisfile-3.dll b/libvorbisfile-3.dll new file mode 100644 index 00000000..c02ad5df Binary files /dev/null and b/libvorbisfile-3.dll differ diff --git a/polygons.cpp b/polygons.cpp new file mode 100644 index 00000000..79c5e4e0 --- /dev/null +++ b/polygons.cpp @@ -0,0 +1,3854 @@ +#define QHPC 5000 + +int qhpc, prehpc; + +hyperpoint hpc[QHPC]; + +bool first; + +bool fatborder; + +void hpcpush(const hyperpoint& h) { + if(vid.usingGL && !first && intval(hpc[qhpc-1], h) > 0.25) { + hyperpoint md = mid(hpc[qhpc-1], h); + hpcpush(md); + } + first = false; + hpc[qhpc++] = h; + } + +struct hpcshape { + int s, e, prio; + }; + +struct polytodraw { + transmatrix V; + int col, start, end, prio; + int outline; + }; + +vector ptds; + +bool ptdsort(const polytodraw& p1, const polytodraw& p2) { + return p1.prio < p2.prio; + } + +#ifndef MOBILE +SDL_Surface *aux; +#endif + +vector ptds2; + +#ifdef GL +#define USEPOLY + +GLuint shapebuffer; + +GLfloat *ourshape = NULL; + +void initPolyForGL() { + if(GL_initialized) return; + GL_initialized = true; + + if(ourshape) delete[] ourshape; + ourshape = new GLfloat[3 * qhpc]; + + // GLfloat ourshape[3*qhpc]; + + int id = 0; + for(int i=0; iw != s->w || aux->h != s->h)) + SDL_FreeSurface(aux); + + if(!aux) { + aux = SDL_CreateRGBSurface(SDL_SWSURFACE,s->w,s->h,32,0,0,0,0); + } + + // SDL_LockSurface(aux); + // memset(aux->pixels, 0, vid.xres * vid.yres * 4); + // SDL_UnlockSurface(aux); + SDL_BlitSurface(s, NULL, aux, NULL); + } +#endif + + for(int i=0; i= 2000 || fatborder) { + Sint16 xmi = 3000, xma = -3000; + for(int t=0; t xmi + 20) for(int x=-1; x<2; x++) for(int y=-1; y<=2; y++) if(x*x+y*y == 1) { + for(int t=0; tw * s->h; + int *a = (int*) s->pixels; + int *b = (int*) aux->pixels; + SDL_LockSurface(aux); + while(qty) { + *a = ((*a) & 0xFF0000) | ((*b) & 0x00FFFF); + a++; b++; qty--; + } + SDL_UnlockSurface(aux); + } + + if(vid.goteyes && vid.usingGL) selectEyeGL(0), selectEyeMask(0); + +#endif +#endif + } + +hpcshape + shFloor[2], shBFloor[2], shMFloor2[2], shWall[2], + shStarFloor[2], shCloudFloor[2], shTriFloor[2], + shFeatherFloor[2], shDemonFloor[2], shCrossFloor[2], shMFloor[2], shCaveFloor[2], + shSemiFeatherFloor[2], shPowerFloor[2], + shSemiFloor[2], shSemiBFloor[2], + shDesertFloor[2], + shCross, shGiantStar[2], shLake, shMirror, + shGem[2], shStar, shDisk, shRing, shDaisy, shTriangle, shNecro, shStatue, shKey, + shBranch, shIBranch, shTentacle, shTentacleX, shILeaf[2], + shMovestar, + shWolf, shYeti, shDemon, shGDemon, shEagle, + shPBody, shPSword, shPHead, shPFace, shGolemhead, shHood, shArmor, + shKnightArmor, shKnightCloak, + shGhost, shEyes, shSlime, shJoint, shWormHead, shTentHead, shShark, + shUser[8][3], shHedgehogBlade, shHedgehogBladePlayer, + shWolfBody, shWolfHead, shWolfLegs, shWolfEyes, + shBigHepta, shBigTriangle, + shFemaleBody, shFemaleHair, shFemaleDress, shWitchDress, + shBugBody, shBugArmor, + shPickAxe, shPike, shFlailBall, shFlailTrunk, shFlailChain, + shBook, shBookCover, shGrail; + +void drawTentacle(hpcshape &h, ld rad, ld var, ld divby) { + for(int i=0; i<=20; i++) + hpcpush(ddi(21, rad + var * sin(i * M_PI/divby)) * ddi(0, crossf * i/20.) * C0); + for(int i=20; i>=0; i--) + hpcpush(ddi(63, rad - var * sin(i * M_PI/divby)) * ddi(0, crossf * i/20.) * C0); + } + +hyperpoint hpxd(ld d, ld x, ld y, ld z) { + hyperpoint H = hpxyz(d*x, d*y, z); + H = mid(H, H); + return H; + } + +void drawDemon(ld d) { + hpcpush(hpxyz(0.098330,0.005996,1.004841)); + hpcpush(hpxyz(0.098350,0.015592,1.004946)); + hpcpush(hpxyz(0.097179,0.027594,1.005090)); + hpcpush(hpxyz(0.088731,0.041967,1.004806)); + hpcpush(hpxyz(0.082695,0.047939,1.004558)); + hpcpush(hpxyz(0.070682,0.061098,1.004355)); + hpcpush(hpxyz(0.075191,0.124914,1.010573)); + hpcpush(hpxyz(0.083954,0.132624,1.012244)); + hpcpush(hpxyz(0.097611,0.134215,1.013677)); + hpcpush(hpxyz(0.112530,0.132100,1.014945)); + hpcpush(hpxyz(0.126233,0.127459,1.015963)); + hpcpush(hpxyz(0.148804,0.116829,1.017738)); + hpcpush(hpxyz(0.170177,0.098653,1.019163)); + hpcpush(hpxyz(0.175203,0.092537,1.019441)); + hpcpush(hpxyz(0.167872,0.107389,1.019663)); + hpcpush(hpxyz(0.150410,0.125752,1.019037)); + hpcpush(hpxyz(0.132974,0.139130,1.018351)); + hpcpush(hpxyz(0.093435,0.163511,1.017578)); + hpcpush(hpxyz(0.064916,0.165353,1.015655)); + hpcpush(hpxyz(0.042697,0.159810,1.013589)); + hpcpush(hpxyz(0.026717,0.148159,1.011269)); + hpcpush(hpxyz(0.018123,0.130482,1.008640)); + hpcpush(hpxyz(0.016784,0.095911,1.004729)); + hpcpush(hpxyz(0.020324,0.078904,1.003314)); + hpcpush(hpxyz(0.017909,0.070441,1.002638)); + hpcpush(hpxyz(0.013123,0.065613,1.002236)); + hpcpush(hpxyz(0.000000,0.063197,1.001995)); + hpcpush(hpxyz(-0.015494,0.057207,1.001755)); + hpcpush(hpxyz(-0.032146,0.038099,1.001242)); + hpcpush(hpxyz(-0.063226,0.021473,1.002227)); + hpcpush(hpxyz(-0.122974,0.008439,1.007568)); + hpcpush(hpxyz(-0.197385,0.012337,1.019369)); + hpcpush(hpxyz(-0.283101,0.000000,1.039301)); + hpcpush(hpxyz(-0.283101,-0.000000,1.039301)); + hpcpush(hpxyz(-0.197385,-0.012337,1.019369)); + hpcpush(hpxyz(-0.122974,-0.008439,1.007568)); + hpcpush(hpxyz(-0.063226,-0.021473,1.002227)); + hpcpush(hpxyz(-0.032146,-0.038099,1.001242)); + hpcpush(hpxyz(-0.015494,-0.057207,1.001755)); + hpcpush(hpxyz(0.000000,-0.063197,1.001995)); + hpcpush(hpxyz(0.013123,-0.065613,1.002236)); + hpcpush(hpxyz(0.017909,-0.070441,1.002638)); + hpcpush(hpxyz(0.020324,-0.078904,1.003314)); + hpcpush(hpxyz(0.016784,-0.095911,1.004729)); + hpcpush(hpxyz(0.018123,-0.130482,1.008640)); + hpcpush(hpxyz(0.026717,-0.148159,1.011269)); + hpcpush(hpxyz(0.042697,-0.159810,1.013589)); + hpcpush(hpxyz(0.064916,-0.165353,1.015655)); + hpcpush(hpxyz(0.093435,-0.163511,1.017578)); + hpcpush(hpxyz(0.132974,-0.139130,1.018351)); + hpcpush(hpxyz(0.150410,-0.125752,1.019037)); + hpcpush(hpxyz(0.167872,-0.107389,1.019663)); + hpcpush(hpxyz(0.175203,-0.092537,1.019441)); + hpcpush(hpxyz(0.170177,-0.098653,1.019163)); + hpcpush(hpxyz(0.148804,-0.116829,1.017738)); + hpcpush(hpxyz(0.126233,-0.127459,1.015963)); + hpcpush(hpxyz(0.112530,-0.132100,1.014945)); + hpcpush(hpxyz(0.097611,-0.134215,1.013677)); + hpcpush(hpxyz(0.083954,-0.132624,1.012244)); + hpcpush(hpxyz(0.075191,-0.124914,1.010573)); + hpcpush(hpxyz(0.070682,-0.061098,1.004355)); + hpcpush(hpxyz(0.082695,-0.047939,1.004558)); + hpcpush(hpxyz(0.088731,-0.041967,1.004806)); + hpcpush(hpxyz(0.097179,-0.027594,1.005090)); + hpcpush(hpxyz(0.098350,-0.015592,1.004946)); + hpcpush(hpxyz(0.098330,-0.005996,1.004841)); + hpcpush(hpxyz(0.098330,0.005996,1.004841)); + } + +hpcshape *last = NULL; + +void bshape(hpcshape& sh, int p) { + if(last) last->e = qhpc; + last = &sh; + last->s = qhpc, last->prio = p; + first = true; + } + +void bshapeend() { + if(last) last->e = qhpc; + last = NULL; + } + +hyperpoint hwolf(double x, double y, double z) { + hyperpoint H = hpxyz(1.5*x, 1.6*y, z); + H = mid(H,H); + return H; + } + +void buildpolys() { + + qhpc = 0; + + bshape(shMovestar, 0); + for(int i=0; i<8; i++) { + hpcpush(spin(M_PI * i/4) * xpush(crossf) * spin(M_PI * i/4) * C0); + hpcpush(spin(M_PI * i/4 + M_PI/8) * xpush(crossf/4) * spin(M_PI * i/4 + M_PI/8) * C0); + } + + // floors + + bshape(shStarFloor[0], 10); + hpcpush(hpxyz(0.267355,0.153145,1.046390)); + hpcpush(hpxyz(0.158858,0.062321,1.014455)); + hpcpush(hpxyz(0.357493,-0.060252,1.063688)); + hpcpush(hpxyz(0.266305,-0.154963,1.046390)); + hpcpush(hpxyz(0.133401,-0.106414,1.014455)); + hpcpush(hpxyz(0.126567,-0.339724,1.063688)); + hpcpush(hpxyz(-0.001050,-0.308108,1.046390)); + hpcpush(hpxyz(-0.025457,-0.168736,1.014455)); + hpcpush(hpxyz(-0.230926,-0.279472,1.063688)); + hpcpush(hpxyz(-0.267355,-0.153145,1.046390)); + hpcpush(hpxyz(-0.158858,-0.062321,1.014455)); + hpcpush(hpxyz(-0.357493,0.060252,1.063688)); + hpcpush(hpxyz(-0.266305,0.154963,1.046390)); + hpcpush(hpxyz(-0.133401,0.106414,1.014455)); + hpcpush(hpxyz(-0.126567,0.339724,1.063688)); + hpcpush(hpxyz(0.001050,0.308108,1.046390)); + hpcpush(hpxyz(0.025457,0.168736,1.014455)); + hpcpush(hpxyz(0.230926,0.279472,1.063688)); + hpcpush(hpxyz(0.267355,0.153145,1.046390)); + + bshape(shStarFloor[1], 10); + hpcpush(hpxyz(-0.012640,0.255336,1.032161)); + hpcpush(hpxyz(0.152259,0.386185,1.082738)); + hpcpush(hpxyz(0.223982,0.275978,1.061288)); + hpcpush(hpxyz(0.191749,0.169082,1.032161)); + hpcpush(hpxyz(0.396864,0.121741,1.082738)); + hpcpush(hpxyz(0.355418,-0.003047,1.061288)); + hpcpush(hpxyz(0.251747,-0.044494,1.032161)); + hpcpush(hpxyz(0.342622,-0.234376,1.082738)); + hpcpush(hpxyz(0.219218,-0.279777,1.061288)); + hpcpush(hpxyz(0.122175,-0.224565,1.032161)); + hpcpush(hpxyz(0.030378,-0.414004,1.082738)); + hpcpush(hpxyz(-0.082058,-0.345829,1.061288)); + hpcpush(hpxyz(-0.099398,-0.235534,1.032161)); + hpcpush(hpxyz(-0.304740,-0.281878,1.082738)); + hpcpush(hpxyz(-0.321543,-0.151465,1.061288)); + hpcpush(hpxyz(-0.246122,-0.069141,1.032161)); + hpcpush(hpxyz(-0.410384,0.062508,1.082738)); + hpcpush(hpxyz(-0.318899,0.156955,1.061288)); + hpcpush(hpxyz(-0.207511,0.149317,1.032161)); + hpcpush(hpxyz(-0.207000,0.359824,1.082738)); + hpcpush(hpxyz(-0.076118,0.347185,1.061288)); + hpcpush(hpxyz(-0.012640,0.255336,1.032161)); + + bshape(shCloudFloor[0], 10); + hpcpush(hpxyz(-0.249278,0.146483,1.040960)); + hpcpush(hpxyz(-0.242058,0.146003,1.039187)); + hpcpush(hpxyz(-0.209868,0.146655,1.032256)); + hpcpush(hpxyz(-0.180387,0.151575,1.027382)); + hpcpush(hpxyz(-0.148230,0.165669,1.024411)); + hpcpush(hpxyz(-0.131141,0.187345,1.025815)); + hpcpush(hpxyz(-0.127578,0.219788,1.031786)); + hpcpush(hpxyz(-0.130923,0.255428,1.040377)); + hpcpush(hpxyz(-0.116050,0.294689,1.048956)); + hpcpush(hpxyz(-0.093271,0.316597,1.053059)); + hpcpush(hpxyz(-0.050041,0.330532,1.054398)); + hpcpush(hpxyz(-0.007791,0.309060,1.046699)); + hpcpush(hpxyz(0.017835,0.271341,1.036313)); + hpcpush(hpxyz(0.017835,0.271341,1.036313)); + hpcpush(hpxyz(0.002219,0.289123,1.040960)); + hpcpush(hpxyz(0.005414,0.282630,1.039187)); + hpcpush(hpxyz(0.022073,0.255079,1.032256)); + hpcpush(hpxyz(0.041075,0.232008,1.027382)); + hpcpush(hpxyz(0.069359,0.211206,1.024411)); + hpcpush(hpxyz(0.096675,0.207244,1.025815)); + hpcpush(hpxyz(0.126553,0.220380,1.031786)); + hpcpush(hpxyz(0.155745,0.241096,1.040377)); + hpcpush(hpxyz(0.197183,0.247847,1.048956)); + hpcpush(hpxyz(0.227545,0.239074,1.053059)); + hpcpush(hpxyz(0.261229,0.208602,1.054398)); + hpcpush(hpxyz(0.263758,0.161278,1.046699)); + hpcpush(hpxyz(0.243906,0.120225,1.036313)); + hpcpush(hpxyz(0.243906,0.120225,1.036313)); + hpcpush(hpxyz(0.251497,0.142640,1.040960)); + hpcpush(hpxyz(0.247471,0.136627,1.039187)); + hpcpush(hpxyz(0.231941,0.108424,1.032256)); + hpcpush(hpxyz(0.221462,0.080432,1.027382)); + hpcpush(hpxyz(0.217589,0.045537,1.024411)); + hpcpush(hpxyz(0.227816,0.019899,1.025815)); + hpcpush(hpxyz(0.254131,0.000592,1.031786)); + hpcpush(hpxyz(0.286668,-0.014331,1.040377)); + hpcpush(hpxyz(0.313233,-0.046842,1.048956)); + hpcpush(hpxyz(0.320816,-0.077523,1.053059)); + hpcpush(hpxyz(0.311269,-0.121929,1.054398)); + hpcpush(hpxyz(0.271550,-0.147783,1.046699)); + hpcpush(hpxyz(0.226071,-0.151116,1.036313)); + hpcpush(hpxyz(0.226071,-0.151116,1.036313)); + hpcpush(hpxyz(0.249278,-0.146483,1.040960)); + hpcpush(hpxyz(0.242058,-0.146003,1.039187)); + hpcpush(hpxyz(0.209868,-0.146655,1.032256)); + hpcpush(hpxyz(0.180387,-0.151575,1.027382)); + hpcpush(hpxyz(0.148230,-0.165669,1.024411)); + hpcpush(hpxyz(0.131141,-0.187345,1.025815)); + hpcpush(hpxyz(0.127578,-0.219788,1.031786)); + hpcpush(hpxyz(0.130923,-0.255428,1.040377)); + hpcpush(hpxyz(0.116050,-0.294689,1.048956)); + hpcpush(hpxyz(0.093271,-0.316597,1.053059)); + hpcpush(hpxyz(0.050041,-0.330532,1.054398)); + hpcpush(hpxyz(0.007791,-0.309060,1.046699)); + hpcpush(hpxyz(-0.017835,-0.271341,1.036313)); + hpcpush(hpxyz(-0.017835,-0.271341,1.036313)); + hpcpush(hpxyz(-0.002219,-0.289123,1.040960)); + hpcpush(hpxyz(-0.005414,-0.282630,1.039187)); + hpcpush(hpxyz(-0.022073,-0.255079,1.032256)); + hpcpush(hpxyz(-0.041075,-0.232008,1.027382)); + hpcpush(hpxyz(-0.069359,-0.211206,1.024411)); + hpcpush(hpxyz(-0.096675,-0.207244,1.025815)); + hpcpush(hpxyz(-0.126553,-0.220380,1.031786)); + hpcpush(hpxyz(-0.155745,-0.241096,1.040377)); + hpcpush(hpxyz(-0.197183,-0.247847,1.048956)); + hpcpush(hpxyz(-0.227545,-0.239074,1.053059)); + hpcpush(hpxyz(-0.261229,-0.208602,1.054398)); + hpcpush(hpxyz(-0.263758,-0.161278,1.046699)); + hpcpush(hpxyz(-0.243906,-0.120225,1.036313)); + hpcpush(hpxyz(-0.243906,-0.120225,1.036313)); + hpcpush(hpxyz(-0.251497,-0.142640,1.040960)); + hpcpush(hpxyz(-0.247471,-0.136627,1.039187)); + hpcpush(hpxyz(-0.231941,-0.108424,1.032256)); + hpcpush(hpxyz(-0.221462,-0.080432,1.027382)); + hpcpush(hpxyz(-0.217589,-0.045537,1.024411)); + hpcpush(hpxyz(-0.227816,-0.019899,1.025815)); + hpcpush(hpxyz(-0.254131,-0.000592,1.031786)); + hpcpush(hpxyz(-0.286668,0.014331,1.040377)); + hpcpush(hpxyz(-0.313233,0.046842,1.048956)); + hpcpush(hpxyz(-0.320816,0.077523,1.053059)); + hpcpush(hpxyz(-0.311269,0.121929,1.054398)); + hpcpush(hpxyz(-0.271550,0.147783,1.046699)); + hpcpush(hpxyz(-0.226071,0.151116,1.036313)); + hpcpush(hpxyz(-0.226071,0.151116,1.036313)); + hpcpush(hpxyz(-0.249278,0.146483,1.040960)); + + bshape(shCrossFloor[0], 10); + hpcpush(hpxyz(-0.283927,0.089050,1.043333)); + hpcpush(hpxyz(-0.363031,0.095818,1.068163)); + hpcpush(hpxyz(-0.386170,0.136539,1.080634)); + hpcpush(hpxyz(-0.370773,0.209082,1.086825)); + hpcpush(hpxyz(-0.207773,0.157096,1.033368)); + hpcpush(hpxyz(-0.213111,0.255207,1.053825)); + hpcpush(hpxyz(-0.045690,0.195109,1.019880)); + hpcpush(hpxyz(-0.053263,0.305287,1.046918)); + hpcpush(hpxyz(0.090089,0.277990,1.041823)); + hpcpush(hpxyz(0.219083,0.201363,1.043333)); + hpcpush(hpxyz(0.264497,0.266484,1.068163)); + hpcpush(hpxyz(0.311331,0.266164,1.080634)); + hpcpush(hpxyz(0.366457,0.216558,1.086825)); + hpcpush(hpxyz(0.239936,0.101388,1.033368)); + hpcpush(hpxyz(0.327571,0.056956,1.053825)); + hpcpush(hpxyz(0.191815,-0.057986,1.019880)); + hpcpush(hpxyz(0.291017,-0.106516,1.046918)); + hpcpush(hpxyz(0.195702,-0.217014,1.041823)); + hpcpush(hpxyz(0.064844,-0.290413,1.043333)); + hpcpush(hpxyz(0.098534,-0.362303,1.068163)); + hpcpush(hpxyz(0.074839,-0.402702,1.080634)); + hpcpush(hpxyz(0.004316,-0.425640,1.086825)); + hpcpush(hpxyz(-0.032163,-0.258485,1.033368)); + hpcpush(hpxyz(-0.114460,-0.312163,1.053825)); + hpcpush(hpxyz(-0.146125,-0.137124,1.019880)); + hpcpush(hpxyz(-0.237755,-0.198770,1.046918)); + hpcpush(hpxyz(-0.285791,-0.060975,1.041823)); + hpcpush(hpxyz(-0.283927,0.089050,1.043333)); + + bshape(shCrossFloor[1], 10); + hpcpush(hpxyz(-0.254099,-0.080041,1.034878)); + hpcpush(hpxyz(-0.326144,-0.061810,1.053656)); + hpcpush(hpxyz(-0.326144,0.061810,1.053656)); + hpcpush(hpxyz(-0.254099,0.080041,1.034878)); + hpcpush(hpxyz(-0.221007,0.148758,1.034878)); + hpcpush(hpxyz(-0.251672,0.216452,1.053656)); + hpcpush(hpxyz(-0.155023,0.293527,1.053656)); + hpcpush(hpxyz(-0.095849,0.248567,1.034878)); + hpcpush(hpxyz(-0.021492,0.265539,1.034878)); + hpcpush(hpxyz(0.012314,0.331721,1.053656)); + hpcpush(hpxyz(0.132834,0.304213,1.053656)); + hpcpush(hpxyz(0.134577,0.229917,1.034878)); + hpcpush(hpxyz(0.194207,0.182364,1.034878)); + hpcpush(hpxyz(0.267027,0.197197,1.053656)); + hpcpush(hpxyz(0.320664,0.085820,1.053656)); + hpcpush(hpxyz(0.263664,0.038135,1.034878)); + hpcpush(hpxyz(0.263664,-0.038135,1.034878)); + hpcpush(hpxyz(0.320664,-0.085820,1.053656)); + hpcpush(hpxyz(0.267027,-0.197197,1.053656)); + hpcpush(hpxyz(0.194207,-0.182364,1.034878)); + hpcpush(hpxyz(0.134577,-0.229917,1.034878)); + hpcpush(hpxyz(0.132834,-0.304213,1.053656)); + hpcpush(hpxyz(0.012314,-0.331721,1.053656)); + hpcpush(hpxyz(-0.021492,-0.265539,1.034878)); + hpcpush(hpxyz(-0.095849,-0.248567,1.034878)); + hpcpush(hpxyz(-0.155023,-0.293527,1.053656)); + hpcpush(hpxyz(-0.251672,-0.216452,1.053656)); + hpcpush(hpxyz(-0.221007,-0.148758,1.034878)); + hpcpush(hpxyz(-0.254099,-0.080041,1.034878)); + + bshape(shCloudFloor[1], 10); + hpcpush(hpxyz(-0.216129,0.195545,1.041609)); + hpcpush(hpxyz(-0.209066,0.211647,1.043314)); + hpcpush(hpxyz(-0.195698,0.234578,1.045622)); + hpcpush(hpxyz(-0.193583,0.272597,1.054411)); + hpcpush(hpxyz(-0.202572,0.304529,1.064788)); + hpcpush(hpxyz(-0.198965,0.336605,1.073727)); + hpcpush(hpxyz(-0.167757,0.354608,1.074192)); + hpcpush(hpxyz(-0.132750,0.357613,1.070285)); + hpcpush(hpxyz(-0.104720,0.351753,1.065221)); + hpcpush(hpxyz(-0.079702,0.340062,1.059242)); + hpcpush(hpxyz(-0.064640,0.331114,1.055374)); + hpcpush(hpxyz(-0.040288,0.308007,1.047135)); + hpcpush(hpxyz(-0.023142,0.289269,1.041255)); + hpcpush(hpxyz(0.018129,0.290897,1.041609)); + hpcpush(hpxyz(0.035122,0.295414,1.043314)); + hpcpush(hpxyz(0.061385,0.299260,1.045622)); + hpcpush(hpxyz(0.092428,0.321310,1.054411)); + hpcpush(hpxyz(0.111789,0.348249,1.064788)); + hpcpush(hpxyz(0.139116,0.365426,1.073727)); + hpcpush(hpxyz(0.172649,0.352252,1.074192)); + hpcpush(hpxyz(0.196825,0.326757,1.070285)); + hpcpush(hpxyz(0.209719,0.301188,1.065221)); + hpcpush(hpxyz(0.216178,0.274339,1.059242)); + hpcpush(hpxyz(0.218573,0.256983,1.055374)); + hpcpush(hpxyz(0.215691,0.223538,1.047135)); + hpcpush(hpxyz(0.211731,0.198449,1.041255)); + hpcpush(hpxyz(0.238736,0.167197,1.041609)); + hpcpush(hpxyz(0.252862,0.156728,1.043314)); + hpcpush(hpxyz(0.272244,0.138593,1.045622)); + hpcpush(hpxyz(0.308838,0.128071,1.054411)); + hpcpush(hpxyz(0.341971,0.129729,1.064788)); + hpcpush(hpxyz(0.372439,0.119075,1.073727)); + hpcpush(hpxyz(0.383047,0.084643,1.074192)); + hpcpush(hpxyz(0.378187,0.049846,1.070285)); + hpcpush(hpxyz(0.366236,0.023822,1.065221)); + hpcpush(hpxyz(0.349271,0.002033,1.059242)); + hpcpush(hpxyz(0.337196,-0.010661,1.055374)); + hpcpush(hpxyz(0.309250,-0.029260,1.047135)); + hpcpush(hpxyz(0.287166,-0.041807,1.041255)); + hpcpush(hpxyz(0.279570,-0.082405,1.041609)); + hpcpush(hpxyz(0.280192,-0.099977,1.043314)); + hpcpush(hpxyz(0.278098,-0.126438,1.045622)); + hpcpush(hpxyz(0.292688,-0.161608,1.054411)); + hpcpush(hpxyz(0.314642,-0.186479,1.064788)); + hpcpush(hpxyz(0.325308,-0.216943,1.073727)); + hpcpush(hpxyz(0.305002,-0.246704,1.074192)); + hpcpush(hpxyz(0.274767,-0.264600,1.070285)); + hpcpush(hpxyz(0.246970,-0.271482,1.065221)); + hpcpush(hpxyz(0.219356,-0.271804,1.059242)); + hpcpush(hpxyz(0.201903,-0.270277,1.055374)); + hpcpush(hpxyz(0.169937,-0.260025,1.047135)); + hpcpush(hpxyz(0.146359,-0.250582,1.041255)); + hpcpush(hpxyz(0.109882,-0.269955,1.041609)); + hpcpush(hpxyz(0.096532,-0.281398,1.043314)); + hpcpush(hpxyz(0.074538,-0.296258,1.045622)); + hpcpush(hpxyz(0.056137,-0.329594,1.054411)); + hpcpush(hpxyz(0.050381,-0.362264,1.064788)); + hpcpush(hpxyz(0.033214,-0.389598,1.073727)); + hpcpush(hpxyz(-0.002715,-0.392278,1.074192)); + hpcpush(hpxyz(-0.035559,-0.379797,1.070285)); + hpcpush(hpxyz(-0.058270,-0.362355,1.065221)); + hpcpush(hpxyz(-0.075738,-0.340967,1.059242)); + hpcpush(hpxyz(-0.085427,-0.326369,1.055374)); + hpcpush(hpxyz(-0.097341,-0.294985,1.047135)); + hpcpush(hpxyz(-0.104659,-0.270663,1.041255)); + hpcpush(hpxyz(-0.142549,-0.254223,1.041609)); + hpcpush(hpxyz(-0.159819,-0.250920,1.043314)); + hpcpush(hpxyz(-0.185150,-0.242990,1.045622)); + hpcpush(hpxyz(-0.222686,-0.249388,1.054411)); + hpcpush(hpxyz(-0.251818,-0.265258,1.064788)); + hpcpush(hpxyz(-0.283891,-0.268878,1.073727)); + hpcpush(hpxyz(-0.308388,-0.242459,1.074192)); + hpcpush(hpxyz(-0.319108,-0.208999,1.070285)); + hpcpush(hpxyz(-0.319631,-0.180367,1.065221)); + hpcpush(hpxyz(-0.313800,-0.153375,1.059242)); + hpcpush(hpxyz(-0.308428,-0.136699,1.055374)); + hpcpush(hpxyz(-0.291320,-0.107816,1.047135)); + hpcpush(hpxyz(-0.276867,-0.086930,1.041255)); + hpcpush(hpxyz(-0.287638,-0.047056,1.041609)); + hpcpush(hpxyz(-0.295823,-0.031495,1.043314)); + hpcpush(hpxyz(-0.305417,-0.006746,1.045622)); + hpcpush(hpxyz(-0.333822,0.018612,1.054411)); + hpcpush(hpxyz(-0.364393,0.031493,1.064788)); + hpcpush(hpxyz(-0.387221,0.054313,1.073727)); + hpcpush(hpxyz(-0.381839,0.089937,1.074192)); + hpcpush(hpxyz(-0.362362,0.119180,1.070285)); + hpcpush(hpxyz(-0.340304,0.137441,1.065221)); + hpcpush(hpxyz(-0.315564,0.149712,1.059242)); + hpcpush(hpxyz(-0.299177,0.155909,1.055374)); + hpcpush(hpxyz(-0.265929,0.160541,1.047135)); + hpcpush(hpxyz(-0.240588,0.162264,1.041255)); + hpcpush(hpxyz(-0.216129,0.195545,1.041609)); + + bshape(shTriFloor[0], 10); + hpcpush(hpxyz(-0.353692,0.244649,1.088554)); + hpcpush(hpxyz(0.388718,0.183982,1.088554)); + hpcpush(hpxyz(-0.035026,-0.428630,1.088554)); + hpcpush(hpxyz(-0.353692,0.244649,1.088554)); + + bshape(shTriFloor[1], 10); + hpcpush(hpxyz(-0.352357,0.009788,1.060307)); + hpcpush(hpxyz(-0.212038,0.281586,1.060307)); + hpcpush(hpxyz(0.087949,0.341344,1.060307)); + hpcpush(hpxyz(0.321709,0.144063,1.060307)); + hpcpush(hpxyz(0.313216,-0.161700,1.060307)); + hpcpush(hpxyz(0.068864,-0.345700,1.060307)); + hpcpush(hpxyz(-0.227343,-0.269381,1.060307)); + hpcpush(hpxyz(-0.352357,0.009788,1.060307)); + + bshape(shFeatherFloor[0], 10); + hpcpush(hpxyz(0.227689,0.169556,1.039515)); + hpcpush(hpxyz(0.333673,0.157023,1.065830)); + hpcpush(hpxyz(0.251378,0.091850,1.035194)); + hpcpush(hpxyz(0.316741,0.073094,1.051507)); + hpcpush(hpxyz(0.260919,0.038655,1.034202)); + hpcpush(hpxyz(0.306256,0.038890,1.046568)); + hpcpush(hpxyz(0.231096,-0.033702,1.026909)); + hpcpush(hpxyz(0.255955,-0.043464,1.033152)); + hpcpush(hpxyz(0.226427,-0.077082,1.028208)); + hpcpush(hpxyz(0.266494,-0.101752,1.039891)); + hpcpush(hpxyz(0.217364,-0.144909,1.033560)); + hpcpush(hpxyz(0.223207,-0.194093,1.042830)); + hpcpush(hpxyz(0.158549,-0.144135,1.022699)); + hpcpush(hpxyz(0.179022,-0.208053,1.036984)); + hpcpush(hpxyz(0.105573,-0.172756,1.020289)); + hpcpush(hpxyz(0.120828,-0.236822,1.034739)); + hpcpush(hpxyz(0.033598,-0.201587,1.020669)); + hpcpush(hpxyz(0.067872,-0.281182,1.040995)); + hpcpush(hpxyz(0.032995,-0.281963,1.039515)); + hpcpush(hpxyz(-0.030851,-0.367481,1.065830)); + hpcpush(hpxyz(-0.046145,-0.263624,1.035194)); + hpcpush(hpxyz(-0.095069,-0.310853,1.051507)); + hpcpush(hpxyz(-0.096984,-0.245290,1.034202)); + hpcpush(hpxyz(-0.119449,-0.284670,1.046568)); + hpcpush(hpxyz(-0.144735,-0.183285,1.026909)); + hpcpush(hpxyz(-0.165618,-0.199931,1.033152)); + hpcpush(hpxyz(-0.179968,-0.157551,1.028208)); + hpcpush(hpxyz(-0.221367,-0.179914,1.039891)); + hpcpush(hpxyz(-0.234177,-0.115788,1.033560)); + hpcpush(hpxyz(-0.279693,-0.096256,1.042830)); + hpcpush(hpxyz(-0.204099,-0.065240,1.022699)); + hpcpush(hpxyz(-0.269690,-0.051011,1.036984)); + hpcpush(hpxyz(-0.202398,-0.005051,1.020289)); + hpcpush(hpxyz(-0.265508,0.013771,1.034739)); + hpcpush(hpxyz(-0.191378,0.071697,1.020669)); + hpcpush(hpxyz(-0.277447,0.081813,1.040995)); + hpcpush(hpxyz(-0.260684,0.112407,1.039515)); + hpcpush(hpxyz(-0.302822,0.210458,1.065830)); + hpcpush(hpxyz(-0.205233,0.171775,1.035194)); + hpcpush(hpxyz(-0.221672,0.237759,1.051507)); + hpcpush(hpxyz(-0.163935,0.206635,1.034202)); + hpcpush(hpxyz(-0.186807,0.245781,1.046568)); + hpcpush(hpxyz(-0.086362,0.216986,1.026909)); + hpcpush(hpxyz(-0.090337,0.243396,1.033152)); + hpcpush(hpxyz(-0.046459,0.234632,1.028208)); + hpcpush(hpxyz(-0.045127,0.281667,1.039891)); + hpcpush(hpxyz(0.016813,0.260697,1.033560)); + hpcpush(hpxyz(0.056486,0.290349,1.042830)); + hpcpush(hpxyz(0.045550,0.209375,1.022699)); + hpcpush(hpxyz(0.090668,0.259064,1.036984)); + hpcpush(hpxyz(0.096825,0.177807,1.020289)); + hpcpush(hpxyz(0.144680,0.223051,1.034739)); + hpcpush(hpxyz(0.157781,0.129890,1.020669)); + hpcpush(hpxyz(0.209575,0.199370,1.040995)); + hpcpush(hpxyz(0.227689,0.169556,1.039515)); + + bshape(shFeatherFloor[1], 10); + hpcpush(hpxyz(-0.097861,0.337622,1.059984)); + hpcpush(hpxyz(-0.034295,0.357645,1.062585)); + hpcpush(hpxyz(-0.014623,0.326578,1.052077)); + hpcpush(hpxyz(0.024557,0.373262,1.067674)); + hpcpush(hpxyz(0.063328,0.316638,1.050843)); + hpcpush(hpxyz(0.088328,0.358219,1.065890)); + hpcpush(hpxyz(0.111793,0.286773,1.046297)); + hpcpush(hpxyz(0.146987,0.328271,1.062717)); + hpcpush(hpxyz(0.170806,0.287930,1.054551)); + hpcpush(hpxyz(0.191056,0.303731,1.062429)); + hpcpush(hpxyz(0.202948,0.287015,1.059984)); + hpcpush(hpxyz(0.258236,0.249801,1.062585)); + hpcpush(hpxyz(0.246211,0.215050,1.052077)); + hpcpush(hpxyz(0.307139,0.213526,1.067674)); + hpcpush(hpxyz(0.287042,0.147909,1.050843)); + hpcpush(hpxyz(0.335138,0.154288,1.065890)); + hpcpush(hpxyz(0.293910,0.091397,1.046297)); + hpcpush(hpxyz(0.348297,0.089755,1.062717)); + hpcpush(hpxyz(0.331608,0.045980,1.054551)); + hpcpush(hpxyz(0.356588,0.039999,1.062429)); + hpcpush(hpxyz(0.350933,0.020280,1.059984)); + hpcpush(hpxyz(0.356310,-0.046149,1.062585)); + hpcpush(hpxyz(0.321644,-0.058414,1.052077)); + hpcpush(hpxyz(0.358439,-0.107000,1.067674)); + hpcpush(hpxyz(0.294608,-0.132199,1.050843)); + hpcpush(hpxyz(0.329582,-0.165824,1.065890)); + hpcpush(hpxyz(0.254707,-0.172803,1.046297)); + hpcpush(hpxyz(0.287333,-0.216349,1.062717)); + hpcpush(hpxyz(0.242703,-0.230594,1.054551)); + hpcpush(hpxyz(0.253601,-0.253853,1.062429)); + hpcpush(hpxyz(0.234659,-0.261726,1.059984)); + hpcpush(hpxyz(0.186075,-0.307347,1.062585)); + hpcpush(hpxyz(0.154871,-0.287892,1.052077)); + hpcpush(hpxyz(0.139827,-0.346952,1.067674)); + hpcpush(hpxyz(0.080328,-0.312758,1.050843)); + hpcpush(hpxyz(0.075845,-0.361068,1.065890)); + hpcpush(hpxyz(0.023704,-0.306879,1.046297)); + hpcpush(hpxyz(0.010001,-0.359537,1.062717)); + hpcpush(hpxyz(-0.028963,-0.333526,1.054551)); + hpcpush(hpxyz(-0.040352,-0.356548,1.062429)); + hpcpush(hpxyz(-0.058319,-0.346647,1.059984)); + hpcpush(hpxyz(-0.124278,-0.337107,1.062585)); + hpcpush(hpxyz(-0.128522,-0.300581,1.052077)); + hpcpush(hpxyz(-0.184077,-0.325642,1.067674)); + hpcpush(hpxyz(-0.194441,-0.257805,1.050843)); + hpcpush(hpxyz(-0.235006,-0.284420,1.065890)); + hpcpush(hpxyz(-0.225148,-0.209869,1.046297)); + hpcpush(hpxyz(-0.274862,-0.231987,1.062717)); + hpcpush(hpxyz(-0.278819,-0.185306,1.054551)); + hpcpush(hpxyz(-0.303920,-0.190756,1.062429)); + hpcpush(hpxyz(-0.307381,-0.170536,1.059984)); + hpcpush(hpxyz(-0.341047,-0.113018,1.062585)); + hpcpush(hpxyz(-0.315136,-0.086927,1.052077)); + hpcpush(hpxyz(-0.369368,-0.059118,1.067674)); + hpcpush(hpxyz(-0.322791,-0.008719,1.050843)); + hpcpush(hpxyz(-0.368892,0.006402,1.065890)); + hpcpush(hpxyz(-0.304459,0.045177,1.046297)); + hpcpush(hpxyz(-0.352748,0.070255,1.062717)); + hpcpush(hpxyz(-0.318719,0.102453,1.054551)); + hpcpush(hpxyz(-0.338629,0.118680,1.062429)); + hpcpush(hpxyz(-0.324979,0.133993,1.059984)); + hpcpush(hpxyz(-0.301001,0.196175,1.062585)); + hpcpush(hpxyz(-0.264446,0.192185,1.052077)); + hpcpush(hpxyz(-0.276517,0.251924,1.067674)); + hpcpush(hpxyz(-0.208074,0.246932,1.050843)); + hpcpush(hpxyz(-0.224995,0.292403,1.065890)); + hpcpush(hpxyz(-0.154507,0.266203,1.046297)); + hpcpush(hpxyz(-0.165008,0.319593,1.062717)); + hpcpush(hpxyz(-0.118617,0.313063,1.054551)); + hpcpush(hpxyz(-0.118344,0.338747,1.062429)); + hpcpush(hpxyz(-0.097861,0.337622,1.059984)); + + bshape(shSemiFeatherFloor[0], 10); + hpcpush(hpxyz(-0.213723,0.142000,1.032396)); + hpcpush(hpxyz(-0.217805,0.186740,1.040342)); + hpcpush(hpxyz(-0.168303,0.178633,1.029677)); + hpcpush(hpxyz(-0.165430,0.203978,1.033912)); + hpcpush(hpxyz(-0.105630,0.181755,1.021857)); + hpcpush(hpxyz(-0.121309,0.236968,1.034828)); + hpcpush(hpxyz(-0.041402,0.211323,1.022923)); + hpcpush(hpxyz(-0.057879,0.276895,1.039240)); + hpcpush(hpxyz(-0.017811,0.253866,1.031874)); + hpcpush(hpxyz(0.017667,0.368934,1.066032)); + hpcpush(hpxyz(0.047389,0.274022,1.037947)); + hpcpush(hpxyz(0.080505,0.307761,1.049380)); + hpcpush(hpxyz(0.077701,0.240665,1.031483)); + hpcpush(hpxyz(0.118416,0.268671,1.042212)); + hpcpush(hpxyz(0.146146,0.160920,1.023354)); + hpcpush(hpxyz(0.177400,0.199591,1.035040)); + hpcpush(hpxyz(0.182840,0.137845,1.025881)); + hpcpush(hpxyz(0.210035,0.188620,1.039082)); + hpcpush(hpxyz(0.224749,0.113626,1.031224)); + hpcpush(hpxyz(0.281767,0.097057,1.043462)); + hpcpush(hpxyz(0.212978,0.071571,1.024930)); + hpcpush(hpxyz(0.267866,0.042710,1.036135)); + hpcpush(hpxyz(0.209124,0.016525,1.021766)); + hpcpush(hpxyz(0.255362,-0.017839,1.032244)); + hpcpush(hpxyz(0.214280,-0.046220,1.023744)); + hpcpush(hpxyz(0.270979,-0.083301,1.039408)); + hpcpush(hpxyz(0.265581,-0.128638,1.042632)); + hpcpush(hpxyz(0.025000,0.006441,1.000333)); + hpcpush(hpxyz(-0.213723,0.142000,1.032396)); + + bshape(shSemiFeatherFloor[1], 10); + hpcpush(hpxyz(-0.260056,0.104281,1.038510)); + hpcpush(hpxyz(0.016285,-0.045687,1.001176)); + hpcpush(hpxyz(0.294213,-0.200108,1.061416)); + hpcpush(hpxyz(0.203762,-0.171240,1.034815)); + hpcpush(hpxyz(0.218578,-0.231670,1.049499)); + hpcpush(hpxyz(0.162724,-0.207729,1.034229)); + hpcpush(hpxyz(0.184841,-0.241991,1.045335)); + hpcpush(hpxyz(0.080474,-0.212574,1.025507)); + hpcpush(hpxyz(0.082238,-0.239152,1.031483)); + hpcpush(hpxyz(0.040630,-0.227735,1.026408)); + hpcpush(hpxyz(0.050962,-0.289632,1.042345)); + hpcpush(hpxyz(-0.023848,-0.250638,1.031207)); + hpcpush(hpxyz(-0.047106,-0.286037,1.041171)); + hpcpush(hpxyz(-0.055913,-0.224791,1.026478)); + hpcpush(hpxyz(-0.096323,-0.258790,1.037425)); + hpcpush(hpxyz(-0.110786,-0.189815,1.023867)); + hpcpush(hpxyz(-0.154769,-0.220600,1.035673)); + hpcpush(hpxyz(-0.166545,-0.156525,1.025786)); + hpcpush(hpxyz(-0.220248,-0.191486,1.041718)); + hpcpush(hpxyz(-0.226246,-0.155963,1.037069)); + hpcpush(hpxyz(-0.331380,-0.170431,1.067173)); + hpcpush(hpxyz(-0.264008,-0.097302,1.038830)); + hpcpush(hpxyz(-0.308875,-0.070140,1.048963)); + hpcpush(hpxyz(-0.282501,-0.040835,1.039940)); + hpcpush(hpxyz(-0.303566,-0.023046,1.045315)); + hpcpush(hpxyz(-0.264959,0.005751,1.034522)); + hpcpush(hpxyz(-0.231085,0.042569,1.027235)); + hpcpush(hpxyz(-0.257805,0.048589,1.033840)); + hpcpush(hpxyz(-0.232591,0.068009,1.028943)); + hpcpush(hpxyz(-0.260056,0.104281,1.038510)); + + bshape(shDemonFloor[1], 10); + hpcpush(hpxyz(-0.226625,-0.098204,1.030050)); + hpcpush(hpxyz(-0.248360,-0.079830,1.033468)); + hpcpush(hpxyz(-0.282817,-0.064277,1.041209)); + hpcpush(hpxyz(-0.267165,-0.033078,1.035602)); + hpcpush(hpxyz(-0.265427,-0.008890,1.034665)); + hpcpush(hpxyz(-0.192052,-0.006156,1.018294)); + hpcpush(hpxyz(-0.183253,-0.047966,1.017783)); + hpcpush(hpxyz(-0.143185,-0.036403,1.010855)); + hpcpush(hpxyz(-0.143048,-0.019396,1.010366)); + hpcpush(hpxyz(-0.166019,-0.021973,1.013926)); + hpcpush(hpxyz(-0.166019,0.021973,1.013926)); + hpcpush(hpxyz(-0.143048,0.019396,1.010366)); + hpcpush(hpxyz(-0.143185,0.036403,1.010855)); + hpcpush(hpxyz(-0.183253,0.047966,1.017783)); + hpcpush(hpxyz(-0.192052,0.006156,1.018294)); + hpcpush(hpxyz(-0.265427,0.008890,1.034665)); + hpcpush(hpxyz(-0.267165,0.033078,1.035602)); + hpcpush(hpxyz(-0.282817,0.064277,1.041209)); + hpcpush(hpxyz(-0.248360,0.079830,1.033468)); + hpcpush(hpxyz(-0.226625,0.098204,1.030050)); + hpcpush(hpxyz(-0.218077,0.115953,1.030050)); + hpcpush(hpxyz(-0.217264,0.144403,1.033468)); + hpcpush(hpxyz(-0.226587,0.181040,1.041209)); + hpcpush(hpxyz(-0.192436,0.188254,1.035602)); + hpcpush(hpxyz(-0.172442,0.201977,1.034665)); + hpcpush(hpxyz(-0.124555,0.146314,1.018294)); + hpcpush(hpxyz(-0.151758,0.113367,1.017783)); + hpcpush(hpxyz(-0.117735,0.089250,1.010855)); + hpcpush(hpxyz(-0.104354,0.099746,1.010366)); + hpcpush(hpxyz(-0.120690,0.116099,1.013926)); + hpcpush(hpxyz(-0.086332,0.143499,1.013926)); + hpcpush(hpxyz(-0.074024,0.123933,1.010366)); + hpcpush(hpxyz(-0.060813,0.134643,1.010855)); + hpcpush(hpxyz(-0.076756,0.173179,1.017783)); + hpcpush(hpxyz(-0.114930,0.153990,1.018294)); + hpcpush(hpxyz(-0.158541,0.213062,1.034665)); + hpcpush(hpxyz(-0.140713,0.229501,1.035602)); + hpcpush(hpxyz(-0.126080,0.261191,1.041209)); + hpcpush(hpxyz(-0.092436,0.243949,1.033468)); + hpcpush(hpxyz(-0.064519,0.238411,1.030050)); + hpcpush(hpxyz(-0.045313,0.242795,1.030050)); + hpcpush(hpxyz(-0.022563,0.259897,1.033468)); + hpcpush(hpxyz(0.000268,0.290029,1.041209)); + hpcpush(hpxyz(0.027202,0.267827,1.035602)); + hpcpush(hpxyz(0.050396,0.260751,1.034665)); + hpcpush(hpxyz(0.036734,0.188606,1.018294)); + hpcpush(hpxyz(-0.005985,0.189332,1.017783)); + hpcpush(hpxyz(-0.003629,0.147695,1.010855)); + hpcpush(hpxyz(0.012921,0.143777,1.010366)); + hpcpush(hpxyz(0.015520,0.166746,1.013926)); + hpcpush(hpxyz(0.058365,0.156967,1.013926)); + hpcpush(hpxyz(0.050741,0.135145,1.010366)); + hpcpush(hpxyz(0.067352,0.131495,1.010855)); + hpcpush(hpxyz(0.087541,0.167986,1.017783)); + hpcpush(hpxyz(0.048737,0.185867,1.018294)); + hpcpush(hpxyz(0.067730,0.256794,1.034665)); + hpcpush(hpxyz(0.091698,0.253106,1.035602)); + hpcpush(hpxyz(0.125598,0.261424,1.041209)); + hpcpush(hpxyz(0.133094,0.224370,1.033468)); + hpcpush(hpxyz(0.146171,0.199090,1.030050)); + hpcpush(hpxyz(0.161573,0.186808,1.030050)); + hpcpush(hpxyz(0.189128,0.179684,1.033468)); + hpcpush(hpxyz(0.226921,0.180621,1.041209)); + hpcpush(hpxyz(0.226355,0.145720,1.035602)); + hpcpush(hpxyz(0.235285,0.123174,1.034665)); + hpcpush(hpxyz(0.170362,0.088874,1.018294)); + hpcpush(hpxyz(0.144294,0.122726,1.017783)); + hpcpush(hpxyz(0.113211,0.094924,1.010855)); + hpcpush(hpxyz(0.120466,0.079542,1.010366)); + hpcpush(hpxyz(0.140044,0.091830,1.013926)); + hpcpush(hpxyz(0.159111,0.052236,1.013926)); + hpcpush(hpxyz(0.137297,0.044591,1.010366)); + hpcpush(hpxyz(0.144800,0.029328,1.010855)); + hpcpush(hpxyz(0.185917,0.036295,1.017783)); + hpcpush(hpxyz(0.175703,0.077782,1.018294)); + hpcpush(hpxyz(0.242999,0.107155,1.034665)); + hpcpush(hpxyz(0.255059,0.086117,1.035602)); + hpcpush(hpxyz(0.282698,0.064799,1.041209)); + hpcpush(hpxyz(0.258402,0.035835,1.033468)); + hpcpush(hpxyz(0.246791,0.009850,1.030050)); + hpcpush(hpxyz(0.246791,-0.009850,1.030050)); + hpcpush(hpxyz(0.258402,-0.035835,1.033468)); + hpcpush(hpxyz(0.282698,-0.064799,1.041209)); + hpcpush(hpxyz(0.255059,-0.086117,1.035602)); + hpcpush(hpxyz(0.242999,-0.107155,1.034665)); + hpcpush(hpxyz(0.175703,-0.077782,1.018294)); + hpcpush(hpxyz(0.185917,-0.036295,1.017783)); + hpcpush(hpxyz(0.144800,-0.029328,1.010855)); + hpcpush(hpxyz(0.137297,-0.044591,1.010366)); + hpcpush(hpxyz(0.159111,-0.052236,1.013926)); + hpcpush(hpxyz(0.140044,-0.091830,1.013926)); + hpcpush(hpxyz(0.120466,-0.079542,1.010366)); + hpcpush(hpxyz(0.113211,-0.094924,1.010855)); + hpcpush(hpxyz(0.144294,-0.122726,1.017783)); + hpcpush(hpxyz(0.170362,-0.088874,1.018294)); + hpcpush(hpxyz(0.235285,-0.123174,1.034665)); + hpcpush(hpxyz(0.226355,-0.145720,1.035602)); + hpcpush(hpxyz(0.226921,-0.180621,1.041209)); + hpcpush(hpxyz(0.189128,-0.179684,1.033468)); + hpcpush(hpxyz(0.161573,-0.186808,1.030050)); + hpcpush(hpxyz(0.146171,-0.199090,1.030050)); + hpcpush(hpxyz(0.133094,-0.224370,1.033468)); + hpcpush(hpxyz(0.125598,-0.261424,1.041209)); + hpcpush(hpxyz(0.091698,-0.253106,1.035602)); + hpcpush(hpxyz(0.067730,-0.256794,1.034665)); + hpcpush(hpxyz(0.048737,-0.185867,1.018294)); + hpcpush(hpxyz(0.087541,-0.167986,1.017783)); + hpcpush(hpxyz(0.067352,-0.131495,1.010855)); + hpcpush(hpxyz(0.050741,-0.135145,1.010366)); + hpcpush(hpxyz(0.058365,-0.156967,1.013926)); + hpcpush(hpxyz(0.015520,-0.166746,1.013926)); + hpcpush(hpxyz(0.012921,-0.143777,1.010366)); + hpcpush(hpxyz(-0.003629,-0.147695,1.010855)); + hpcpush(hpxyz(-0.005985,-0.189332,1.017783)); + hpcpush(hpxyz(0.036734,-0.188606,1.018294)); + hpcpush(hpxyz(0.050396,-0.260751,1.034665)); + hpcpush(hpxyz(0.027202,-0.267827,1.035602)); + hpcpush(hpxyz(0.000268,-0.290029,1.041209)); + hpcpush(hpxyz(-0.022563,-0.259897,1.033468)); + hpcpush(hpxyz(-0.045313,-0.242795,1.030050)); + hpcpush(hpxyz(-0.064519,-0.238411,1.030050)); + hpcpush(hpxyz(-0.092436,-0.243949,1.033468)); + hpcpush(hpxyz(-0.126080,-0.261191,1.041209)); + hpcpush(hpxyz(-0.140713,-0.229501,1.035602)); + hpcpush(hpxyz(-0.158541,-0.213062,1.034665)); + hpcpush(hpxyz(-0.114930,-0.153990,1.018294)); + hpcpush(hpxyz(-0.076756,-0.173179,1.017783)); + hpcpush(hpxyz(-0.060813,-0.134643,1.010855)); + hpcpush(hpxyz(-0.074024,-0.123933,1.010366)); + hpcpush(hpxyz(-0.086332,-0.143499,1.013926)); + hpcpush(hpxyz(-0.120690,-0.116099,1.013926)); + hpcpush(hpxyz(-0.104354,-0.099746,1.010366)); + hpcpush(hpxyz(-0.117735,-0.089250,1.010855)); + hpcpush(hpxyz(-0.151758,-0.113367,1.017783)); + hpcpush(hpxyz(-0.124555,-0.146314,1.018294)); + hpcpush(hpxyz(-0.172442,-0.201977,1.034665)); + hpcpush(hpxyz(-0.192436,-0.188254,1.035602)); + hpcpush(hpxyz(-0.226587,-0.181040,1.041209)); + hpcpush(hpxyz(-0.217264,-0.144403,1.033468)); + hpcpush(hpxyz(-0.218077,-0.115953,1.030050)); + hpcpush(hpxyz(-0.226625,-0.098204,1.030050)); + + bshape(shDemonFloor[0], 10); + hpcpush(hpxyz(-0.301493,-0.143505,1.054273)); + hpcpush(hpxyz(-0.286951,-0.089187,1.044172)); + hpcpush(hpxyz(-0.265835,-0.083073,1.038060)); + hpcpush(hpxyz(-0.254617,-0.091662,1.035969)); + hpcpush(hpxyz(-0.235025,-0.098559,1.031964)); + hpcpush(hpxyz(-0.212515,-0.090006,1.026286)); + hpcpush(hpxyz(-0.195614,-0.068094,1.021226)); + hpcpush(hpxyz(-0.191005,-0.038201,1.018795)); + hpcpush(hpxyz(-0.190797,-0.019695,1.018230)); + hpcpush(hpxyz(-0.209527,-0.022317,1.021959)); + hpcpush(hpxyz(-0.209825,-0.043455,1.022700)); + hpcpush(hpxyz(-0.217026,-0.061116,1.025103)); + hpcpush(hpxyz(-0.229748,-0.071561,1.028545)); + hpcpush(hpxyz(-0.245216,-0.072048,1.032144)); + hpcpush(hpxyz(-0.259160,-0.060979,1.034834)); + hpcpush(hpxyz(-0.268975,-0.048441,1.036674)); + hpcpush(hpxyz(-0.279355,-0.049976,1.039489)); + hpcpush(hpxyz(-0.293619,-0.069848,1.044553)); + hpcpush(hpxyz(-0.299119,-0.088435,1.047517)); + hpcpush(hpxyz(-0.309915,-0.111622,1.052856)); + hpcpush(hpxyz(-0.326351,-0.118070,1.058511)); + hpcpush(hpxyz(-0.344537,-0.119314,1.064397)); + hpcpush(hpxyz(-0.371612,-0.115703,1.073072)); + hpcpush(hpxyz(-0.386986,-0.108411,1.077734)); + hpcpush(hpxyz(-0.395533,-0.101984,1.080207)); + hpcpush(hpxyz(-0.372081,-0.100489,1.071701)); + hpcpush(hpxyz(-0.352370,-0.089767,1.064059)); + hpcpush(hpxyz(-0.339559,-0.070299,1.058415)); + hpcpush(hpxyz(-0.338745,-0.051606,1.057077)); + hpcpush(hpxyz(-0.343230,-0.037106,1.057915)); + hpcpush(hpxyz(-0.346305,-0.026537,1.058599)); + hpcpush(hpxyz(-0.349398,-0.006643,1.059303)); + hpcpush(hpxyz(-0.344437,0.011923,1.057724)); + hpcpush(hpxyz(-0.344437,-0.011923,1.057724)); + hpcpush(hpxyz(-0.349398,0.006643,1.059303)); + hpcpush(hpxyz(-0.346305,0.026537,1.058599)); + hpcpush(hpxyz(-0.343230,0.037106,1.057915)); + hpcpush(hpxyz(-0.338745,0.051606,1.057077)); + hpcpush(hpxyz(-0.339559,0.070299,1.058415)); + hpcpush(hpxyz(-0.352370,0.089767,1.064059)); + hpcpush(hpxyz(-0.372081,0.100489,1.071701)); + hpcpush(hpxyz(-0.395533,0.101984,1.080207)); + hpcpush(hpxyz(-0.386986,0.108411,1.077734)); + hpcpush(hpxyz(-0.371612,0.115703,1.073072)); + hpcpush(hpxyz(-0.344537,0.119314,1.064397)); + hpcpush(hpxyz(-0.326351,0.118070,1.058511)); + hpcpush(hpxyz(-0.309915,0.111622,1.052856)); + hpcpush(hpxyz(-0.299119,0.088435,1.047517)); + hpcpush(hpxyz(-0.293619,0.069848,1.044553)); + hpcpush(hpxyz(-0.279355,0.049976,1.039489)); + hpcpush(hpxyz(-0.268975,0.048441,1.036674)); + hpcpush(hpxyz(-0.259160,0.060979,1.034834)); + hpcpush(hpxyz(-0.245216,0.072048,1.032144)); + hpcpush(hpxyz(-0.229748,0.071561,1.028545)); + hpcpush(hpxyz(-0.217026,0.061116,1.025103)); + hpcpush(hpxyz(-0.209825,0.043455,1.022700)); + hpcpush(hpxyz(-0.209527,0.022317,1.021959)); + hpcpush(hpxyz(-0.190797,0.019695,1.018230)); + hpcpush(hpxyz(-0.191005,0.038201,1.018795)); + hpcpush(hpxyz(-0.195614,0.068094,1.021226)); + hpcpush(hpxyz(-0.212515,0.090006,1.026286)); + hpcpush(hpxyz(-0.235025,0.098559,1.031964)); + hpcpush(hpxyz(-0.254617,0.091662,1.035969)); + hpcpush(hpxyz(-0.265835,0.083073,1.038060)); + hpcpush(hpxyz(-0.286951,0.089187,1.044172)); + hpcpush(hpxyz(-0.301493,0.143505,1.054273)); + hpcpush(hpxyz(0.026467,0.332853,1.054273)); + hpcpush(hpxyz(0.066237,0.293100,1.044172)); + hpcpush(hpxyz(0.060974,0.271757,1.038060)); + hpcpush(hpxyz(0.047927,0.266336,1.035969)); + hpcpush(hpxyz(0.032158,0.252817,1.031964)); + hpcpush(hpxyz(0.028310,0.229046,1.026286)); + hpcpush(hpxyz(0.038836,0.203454,1.021226)); + hpcpush(hpxyz(0.062419,0.184516,1.018795)); + hpcpush(hpxyz(0.078342,0.175083,1.018230)); + hpcpush(hpxyz(0.085437,0.192614,1.021959)); + hpcpush(hpxyz(0.067279,0.203441,1.022700)); + hpcpush(hpxyz(0.055584,0.218508,1.025103)); + hpcpush(hpxyz(0.052900,0.234748,1.028545)); + hpcpush(hpxyz(0.060213,0.248387,1.032144)); + hpcpush(hpxyz(0.076771,0.254928,1.034834)); + hpcpush(hpxyz(0.092536,0.257159,1.036674)); + hpcpush(hpxyz(0.096397,0.266917,1.039489)); + hpcpush(hpxyz(0.086320,0.289205,1.044553)); + hpcpush(hpxyz(0.072972,0.303262,1.047517)); + hpcpush(hpxyz(0.058290,0.324205,1.052856)); + hpcpush(hpxyz(0.060924,0.341663,1.058511)); + hpcpush(hpxyz(0.068939,0.358035,1.064397)); + hpcpush(hpxyz(0.085604,0.379677,1.073072)); + hpcpush(hpxyz(0.099606,0.389345,1.077734)); + hpcpush(hpxyz(0.109446,0.393534,1.080207)); + hpcpush(hpxyz(0.099014,0.372476,1.071701)); + hpcpush(hpxyz(0.098444,0.350045,1.064059)); + hpcpush(hpxyz(0.108898,0.329216,1.058415)); + hpcpush(hpxyz(0.124681,0.319165,1.057077)); + hpcpush(hpxyz(0.139480,0.315799,1.057915)); + hpcpush(hpxyz(0.150171,0.313177,1.058599)); + hpcpush(hpxyz(0.168947,0.305909,1.059303)); + hpcpush(hpxyz(0.182544,0.292330,1.057724)); + hpcpush(hpxyz(0.161893,0.304253,1.057724)); + hpcpush(hpxyz(0.180452,0.299267,1.059303)); + hpcpush(hpxyz(0.196134,0.286640,1.058599)); + hpcpush(hpxyz(0.203750,0.278693,1.057915)); + hpcpush(hpxyz(0.214064,0.267559,1.057077)); + hpcpush(hpxyz(0.230660,0.258917,1.058415)); + hpcpush(hpxyz(0.253926,0.260278,1.064059)); + hpcpush(hpxyz(0.273066,0.271987,1.071701)); + hpcpush(hpxyz(0.286087,0.291550,1.080207)); + hpcpush(hpxyz(0.287380,0.280934,1.077734)); + hpcpush(hpxyz(0.286008,0.263974,1.073072)); + hpcpush(hpxyz(0.275598,0.238721,1.064397)); + hpcpush(hpxyz(0.265427,0.223593,1.058511)); + hpcpush(hpxyz(0.251625,0.212583,1.052856)); + hpcpush(hpxyz(0.226146,0.214827,1.047517)); + hpcpush(hpxyz(0.207299,0.219357,1.044553)); + hpcpush(hpxyz(0.182958,0.216941,1.039489)); + hpcpush(hpxyz(0.176438,0.208718,1.036674)); + hpcpush(hpxyz(0.182389,0.193949,1.034834)); + hpcpush(hpxyz(0.185004,0.176339,1.032144)); + hpcpush(hpxyz(0.176847,0.163187,1.028545)); + hpcpush(hpxyz(0.161441,0.157392,1.025103)); + hpcpush(hpxyz(0.142545,0.159986,1.022700)); + hpcpush(hpxyz(0.124090,0.170298,1.021959)); + hpcpush(hpxyz(0.112455,0.155388,1.018230)); + hpcpush(hpxyz(0.128586,0.146315,1.018795)); + hpcpush(hpxyz(0.156778,0.135360,1.021226)); + hpcpush(hpxyz(0.184205,0.139040,1.026286)); + hpcpush(hpxyz(0.202867,0.154258,1.031964)); + hpcpush(hpxyz(0.206690,0.174674,1.035969)); + hpcpush(hpxyz(0.204861,0.188683,1.038060)); + hpcpush(hpxyz(0.220714,0.203913,1.044172)); + hpcpush(hpxyz(0.275026,0.189348,1.054273)); + hpcpush(hpxyz(0.275026,-0.189348,1.054273)); + hpcpush(hpxyz(0.220714,-0.203913,1.044172)); + hpcpush(hpxyz(0.204861,-0.188683,1.038060)); + hpcpush(hpxyz(0.206690,-0.174674,1.035969)); + hpcpush(hpxyz(0.202867,-0.154258,1.031964)); + hpcpush(hpxyz(0.184205,-0.139040,1.026286)); + hpcpush(hpxyz(0.156778,-0.135360,1.021226)); + hpcpush(hpxyz(0.128586,-0.146315,1.018795)); + hpcpush(hpxyz(0.112455,-0.155388,1.018230)); + hpcpush(hpxyz(0.124090,-0.170298,1.021959)); + hpcpush(hpxyz(0.142545,-0.159986,1.022700)); + hpcpush(hpxyz(0.161441,-0.157392,1.025103)); + hpcpush(hpxyz(0.176847,-0.163187,1.028545)); + hpcpush(hpxyz(0.185004,-0.176339,1.032144)); + hpcpush(hpxyz(0.182389,-0.193949,1.034834)); + hpcpush(hpxyz(0.176438,-0.208718,1.036674)); + hpcpush(hpxyz(0.182958,-0.216941,1.039489)); + hpcpush(hpxyz(0.207299,-0.219357,1.044553)); + hpcpush(hpxyz(0.226146,-0.214827,1.047517)); + hpcpush(hpxyz(0.251625,-0.212583,1.052856)); + hpcpush(hpxyz(0.265427,-0.223593,1.058511)); + hpcpush(hpxyz(0.275598,-0.238721,1.064397)); + hpcpush(hpxyz(0.286008,-0.263974,1.073072)); + hpcpush(hpxyz(0.287380,-0.280934,1.077734)); + hpcpush(hpxyz(0.286087,-0.291550,1.080207)); + hpcpush(hpxyz(0.273066,-0.271987,1.071701)); + hpcpush(hpxyz(0.253926,-0.260278,1.064059)); + hpcpush(hpxyz(0.230660,-0.258917,1.058415)); + hpcpush(hpxyz(0.214064,-0.267559,1.057077)); + hpcpush(hpxyz(0.203750,-0.278693,1.057915)); + hpcpush(hpxyz(0.196134,-0.286640,1.058599)); + hpcpush(hpxyz(0.180452,-0.299267,1.059303)); + hpcpush(hpxyz(0.161893,-0.304253,1.057724)); + hpcpush(hpxyz(0.182544,-0.292330,1.057724)); + hpcpush(hpxyz(0.168947,-0.305909,1.059303)); + hpcpush(hpxyz(0.150171,-0.313177,1.058599)); + hpcpush(hpxyz(0.139480,-0.315799,1.057915)); + hpcpush(hpxyz(0.124681,-0.319165,1.057077)); + hpcpush(hpxyz(0.108898,-0.329216,1.058415)); + hpcpush(hpxyz(0.098444,-0.350045,1.064059)); + hpcpush(hpxyz(0.099014,-0.372476,1.071701)); + hpcpush(hpxyz(0.109446,-0.393534,1.080207)); + hpcpush(hpxyz(0.099606,-0.389345,1.077734)); + hpcpush(hpxyz(0.085604,-0.379677,1.073072)); + hpcpush(hpxyz(0.068939,-0.358035,1.064397)); + hpcpush(hpxyz(0.060924,-0.341663,1.058511)); + hpcpush(hpxyz(0.058290,-0.324205,1.052856)); + hpcpush(hpxyz(0.072972,-0.303262,1.047517)); + hpcpush(hpxyz(0.086320,-0.289205,1.044553)); + hpcpush(hpxyz(0.096397,-0.266917,1.039489)); + hpcpush(hpxyz(0.092536,-0.257159,1.036674)); + hpcpush(hpxyz(0.076771,-0.254928,1.034834)); + hpcpush(hpxyz(0.060213,-0.248387,1.032144)); + hpcpush(hpxyz(0.052900,-0.234748,1.028545)); + hpcpush(hpxyz(0.055584,-0.218508,1.025103)); + hpcpush(hpxyz(0.067279,-0.203441,1.022700)); + hpcpush(hpxyz(0.085437,-0.192614,1.021959)); + hpcpush(hpxyz(0.078342,-0.175083,1.018230)); + hpcpush(hpxyz(0.062419,-0.184516,1.018795)); + hpcpush(hpxyz(0.038836,-0.203454,1.021226)); + hpcpush(hpxyz(0.028310,-0.229046,1.026286)); + hpcpush(hpxyz(0.032158,-0.252817,1.031964)); + hpcpush(hpxyz(0.047927,-0.266336,1.035969)); + hpcpush(hpxyz(0.060974,-0.271757,1.038060)); + hpcpush(hpxyz(0.066237,-0.293100,1.044172)); + hpcpush(hpxyz(0.026467,-0.332853,1.054273)); + hpcpush(hpxyz(-0.301493,-0.143505,1.054273)); + + bshape(shCaveFloor[0], 10); + hpcpush(hpxyz(-0.234236,0.156157,1.038870)); + hpcpush(hpxyz(-0.104249,0.246637,1.035228)); + hpcpush(hpxyz(-0.046397,0.291271,1.042589)); + hpcpush(hpxyz(0.016871,0.307576,1.046369)); + hpcpush(hpxyz(0.102393,0.312431,1.052662)); + hpcpush(hpxyz(0.175295,0.270792,1.050741)); + hpcpush(hpxyz(0.252411,0.200098,1.050595)); + hpcpush(hpxyz(0.252354,0.124776,1.038870)); + hpcpush(hpxyz(0.265719,-0.033037,1.035228)); + hpcpush(hpxyz(0.275447,-0.105454,1.042589)); + hpcpush(hpxyz(0.257933,-0.168399,1.046369)); + hpcpush(hpxyz(0.219377,-0.244891,1.052662)); + hpcpush(hpxyz(0.146865,-0.287206,1.050741)); + hpcpush(hpxyz(0.047084,-0.318643,1.050595)); + hpcpush(hpxyz(-0.018118,-0.280933,1.038870)); + hpcpush(hpxyz(-0.161470,-0.213601,1.035228)); + hpcpush(hpxyz(-0.229049,-0.185817,1.042589)); + hpcpush(hpxyz(-0.274804,-0.139177,1.046369)); + hpcpush(hpxyz(-0.321770,-0.067540,1.052662)); + hpcpush(hpxyz(-0.322160,0.016414,1.050741)); + hpcpush(hpxyz(-0.299495,0.118545,1.050595)); + hpcpush(hpxyz(-0.234236,0.156157,1.038870)); + + bshape(shCaveFloor[1], 10); + hpcpush(hpxyz(-0.275790,0.020429,1.037534)); + hpcpush(hpxyz(-0.270081,0.108032,1.041448)); + hpcpush(hpxyz(-0.241466,0.175612,1.043621)); + hpcpush(hpxyz(-0.155980,0.228358,1.037534)); + hpcpush(hpxyz(-0.083930,0.278515,1.041448)); + hpcpush(hpxyz(-0.013253,0.298278,1.043621)); + hpcpush(hpxyz(0.081286,0.264329,1.037534)); + hpcpush(hpxyz(0.165423,0.239270,1.041448)); + hpcpush(hpxyz(0.224940,0.196335,1.043621)); + hpcpush(hpxyz(0.257342,0.101255,1.037534)); + hpcpush(hpxyz(0.290208,0.019850,1.041448)); + hpcpush(hpxyz(0.293748,-0.053452,1.043621)); + hpcpush(hpxyz(0.239614,-0.138066,1.037534)); + hpcpush(hpxyz(0.196461,-0.214518,1.041448)); + hpcpush(hpxyz(0.141358,-0.262989,1.043621)); + hpcpush(hpxyz(0.041452,-0.273421,1.037534)); + hpcpush(hpxyz(-0.045225,-0.287349,1.041448)); + hpcpush(hpxyz(-0.117477,-0.274489,1.043621)); + hpcpush(hpxyz(-0.187924,-0.202884,1.037534)); + hpcpush(hpxyz(-0.252856,-0.143801,1.041448)); + hpcpush(hpxyz(-0.287850,-0.079294,1.043621)); + hpcpush(hpxyz(-0.275790,0.020429,1.037534)); + + bshape(shDesertFloor[0], 10); + hpcpush(hpxyz(-0.122282,0.287492,1.047666)); + hpcpush(hpxyz(-0.111151,0.302069,1.050524)); + hpcpush(hpxyz(-0.092261,0.322915,1.054887)); + hpcpush(hpxyz(-0.071518,0.368383,1.068092)); + hpcpush(hpxyz(-0.014386,0.321713,1.050574)); + hpcpush(hpxyz(0.014126,0.287661,1.040648)); + hpcpush(hpxyz(0.052673,0.283918,1.040857)); + hpcpush(hpxyz(0.144166,0.292263,1.051761)); + hpcpush(hpxyz(0.201841,0.240906,1.048225)); + hpcpush(hpxyz(0.236802,0.171166,1.041812)); + hpcpush(hpxyz(0.187940,0.142834,1.027484)); + hpcpush(hpxyz(0.179062,0.090148,1.019897)); + hpcpush(hpxyz(0.306355,-0.036347,1.046506)); + hpcpush(hpxyz(0.310117,-0.037847,1.047666)); + hpcpush(hpxyz(0.317175,-0.054775,1.050524)); + hpcpush(hpxyz(0.325783,-0.081557,1.054887)); + hpcpush(hpxyz(0.354788,-0.122255,1.068092)); + hpcpush(hpxyz(0.285805,-0.148398,1.050574)); + hpcpush(hpxyz(0.242058,-0.156064,1.040648)); + hpcpush(hpxyz(0.219544,-0.187575,1.040857)); + hpcpush(hpxyz(0.181024,-0.270983,1.051761)); + hpcpush(hpxyz(0.107711,-0.295252,1.048225)); + hpcpush(hpxyz(0.029834,-0.290659,1.041812)); + hpcpush(hpxyz(0.029728,-0.234177,1.027484)); + hpcpush(hpxyz(-0.011460,-0.200146,1.019897)); + hpcpush(hpxyz(-0.184655,-0.247137,1.046506)); + hpcpush(hpxyz(-0.187835,-0.249645,1.047666)); + hpcpush(hpxyz(-0.206024,-0.247294,1.050524)); + hpcpush(hpxyz(-0.233522,-0.241358,1.054887)); + hpcpush(hpxyz(-0.283270,-0.246127,1.068092)); + hpcpush(hpxyz(-0.271419,-0.173315,1.050574)); + hpcpush(hpxyz(-0.256185,-0.131597,1.040648)); + hpcpush(hpxyz(-0.272216,-0.096343,1.040857)); + hpcpush(hpxyz(-0.325190,-0.021280,1.051761)); + hpcpush(hpxyz(-0.309551,0.054346,1.048225)); + hpcpush(hpxyz(-0.266635,0.119493,1.041812)); + hpcpush(hpxyz(-0.217668,0.091343,1.027484)); + hpcpush(hpxyz(-0.167602,0.109998,1.019897)); + hpcpush(hpxyz(-0.121700,0.283485,1.046506)); + hpcpush(hpxyz(-0.122282,0.287492,1.047666)); + + bshape(shDesertFloor[1], 10); + hpcpush(hpxyz(-0.336141,-0.153280,1.066061)); + hpcpush(hpxyz(-0.336530,-0.140779,1.064458)); + hpcpush(hpxyz(-0.323000,-0.116492,1.057308)); + hpcpush(hpxyz(-0.295897,-0.085654,1.046371)); + hpcpush(hpxyz(-0.271537,-0.031871,1.036701)); + hpcpush(hpxyz(-0.271537,0.031871,1.036701)); + hpcpush(hpxyz(-0.295897,0.085654,1.046371)); + hpcpush(hpxyz(-0.323000,0.116492,1.057308)); + hpcpush(hpxyz(-0.336530,0.140779,1.064458)); + hpcpush(hpxyz(-0.336141,0.153280,1.066061)); + hpcpush(hpxyz(-0.329419,0.167237,1.066061)); + hpcpush(hpxyz(-0.319889,0.175335,1.064458)); + hpcpush(hpxyz(-0.292464,0.179900,1.057308)); + hpcpush(hpxyz(-0.251456,0.177937,1.046371)); + hpcpush(hpxyz(-0.194218,0.192425,1.036701)); + hpcpush(hpxyz(-0.144383,0.232167,1.036701)); + hpcpush(hpxyz(-0.117521,0.284746,1.046371)); + hpcpush(hpxyz(-0.110310,0.325163,1.057308)); + hpcpush(hpxyz(-0.099757,0.350884,1.064458)); + hpcpush(hpxyz(-0.089741,0.358374,1.066061)); + hpcpush(hpxyz(-0.074639,0.361821,1.066061)); + hpcpush(hpxyz(-0.062365,0.359418,1.064458)); + hpcpush(hpxyz(-0.041697,0.340824,1.057308)); + hpcpush(hpxyz(-0.017664,0.307538,1.046371)); + hpcpush(hpxyz(0.029351,0.271821,1.036701)); + hpcpush(hpxyz(0.091494,0.257638,1.036701)); + hpcpush(hpxyz(0.149350,0.269418,1.046371)); + hpcpush(hpxyz(0.185445,0.288980,1.057308)); + hpcpush(hpxyz(0.212135,0.296766,1.064458)); + hpcpush(hpxyz(0.224235,0.293605,1.066061)); + hpcpush(hpxyz(0.236346,0.283946,1.066061)); + hpcpush(hpxyz(0.242121,0.272853,1.064458)); + hpcpush(hpxyz(0.240469,0.245100,1.057308)); + hpcpush(hpxyz(0.229430,0.205557,1.046371)); + hpcpush(hpxyz(0.230819,0.146530,1.036701)); + hpcpush(hpxyz(0.258475,0.089101,1.036701)); + hpcpush(hpxyz(0.303758,0.051213,1.046371)); + hpcpush(hpxyz(0.341557,0.035189,1.057308)); + hpcpush(hpxyz(0.364285,0.019177,1.064458)); + hpcpush(hpxyz(0.369358,0.007745,1.066061)); + hpcpush(hpxyz(0.369358,-0.007745,1.066061)); + hpcpush(hpxyz(0.364285,-0.019177,1.064458)); + hpcpush(hpxyz(0.341557,-0.035189,1.057308)); + hpcpush(hpxyz(0.303758,-0.051213,1.046371)); + hpcpush(hpxyz(0.258475,-0.089101,1.036701)); + hpcpush(hpxyz(0.230819,-0.146530,1.036701)); + hpcpush(hpxyz(0.229430,-0.205557,1.046371)); + hpcpush(hpxyz(0.240469,-0.245100,1.057308)); + hpcpush(hpxyz(0.242121,-0.272853,1.064458)); + hpcpush(hpxyz(0.236346,-0.283946,1.066061)); + hpcpush(hpxyz(0.224235,-0.293605,1.066061)); + hpcpush(hpxyz(0.212135,-0.296766,1.064458)); + hpcpush(hpxyz(0.185445,-0.288980,1.057308)); + hpcpush(hpxyz(0.149350,-0.269418,1.046371)); + hpcpush(hpxyz(0.091494,-0.257638,1.036701)); + hpcpush(hpxyz(0.029351,-0.271821,1.036701)); + hpcpush(hpxyz(-0.017664,-0.307538,1.046371)); + hpcpush(hpxyz(-0.041697,-0.340824,1.057308)); + hpcpush(hpxyz(-0.062365,-0.359418,1.064458)); + hpcpush(hpxyz(-0.074639,-0.361821,1.066061)); + hpcpush(hpxyz(-0.089741,-0.358374,1.066061)); + hpcpush(hpxyz(-0.099757,-0.350884,1.064458)); + hpcpush(hpxyz(-0.110310,-0.325163,1.057308)); + hpcpush(hpxyz(-0.117521,-0.284746,1.046371)); + hpcpush(hpxyz(-0.144383,-0.232167,1.036701)); + hpcpush(hpxyz(-0.194218,-0.192425,1.036701)); + hpcpush(hpxyz(-0.251456,-0.177937,1.046371)); + hpcpush(hpxyz(-0.292464,-0.179900,1.057308)); + hpcpush(hpxyz(-0.319889,-0.175335,1.064458)); + hpcpush(hpxyz(-0.329419,-0.167237,1.066061)); + hpcpush(hpxyz(-0.336141,-0.153280,1.066061)); + + bshape(shFloor[0], 11); + for(int t=0; t<=6; t++) hpcpush(ddi(7 + t*14, hexf*.8) * C0); + + bshape(shFloor[1], 11); + for(int t=0; t<=7; t++) hpcpush(ddi(t*12, hexf*.94) * C0); + + for(int d=0; d<2; d++) { + bshape(shSemiFloor[d], 11); + for(int t=0; t<=4; t++) hpcpush(ddi(7 + (3+3*d+t%4)*14, hexf*.8) * C0); + } + + bshape(shMFloor[0], 12); + for(int t=0; t<=6; t++) hpcpush(ddi(7 + t*14, hexf*.7) * C0); + + bshape(shMFloor[1], 12); + for(int t=0; t<=7; t++) hpcpush(ddi(t*12, hexf*.8) * C0); + + bshape(shMFloor2[0], 13); + for(int t=0; t<=6; t++) hpcpush(ddi(7 + t*14, hexf*.6) * C0); + + bshape(shMFloor2[1], 13); + for(int t=0; t<=7; t++) hpcpush(ddi(t*12, hexf*.7) * C0); + + bshape(shBFloor[0], 14); + for(int t=0; t<=6; t++) hpcpush(ddi(7 + t*14, hexf*.1) * C0); + + bshape(shBFloor[1], 14); + for(int t=0; t<=7; t++) hpcpush(ddi(t*12, hexf*.1) * C0); + + for(int d=0; d<2; d++) { + bshape(shSemiBFloor[d], 11); + for(int t=0; t<=4; t++) hpcpush(ddi(7 + (3+3*d+t%4)*14, hexf*.1) * C0); + } + + // walls etc + + bshape(shGiantStar[1], 12); + for(int t=0; t<=7; t++) hpcpush(ddi(t*36, -hexf*2.4) * C0); + + bshape(shGiantStar[0], 12); + for(int t=0; t<=6; t++) { + hpcpush(ddi(t*14, -hexf*2.4) * C0); + hpcpush(ddi(t*14+7, hexf*1.5) * C0); + } + hpcpush(ddi(0, -hexf*2.4) * C0); + + bshape(shPowerFloor[0], 12); + hpcpush(hpxyz(0.188696,0.349290,1.075923)); + hpcpush(hpxyz(0.246724,0.011920,1.030056)); + hpcpush(hpxyz(0.208146,-0.338061,1.075923)); + hpcpush(hpxyz(-0.113039,-0.219629,1.030056)); + hpcpush(hpxyz(-0.396842,-0.011229,1.075923)); + hpcpush(hpxyz(-0.133685,0.207709,1.030056)); + hpcpush(hpxyz(0.188696,0.349290,1.075923)); + + bshape(shPowerFloor[1], 12); + hpcpush(hpxyz(0.563851,-0.000804,1.148010)); + hpcpush(hpxyz(0.151110,-0.073482,1.014019)); + hpcpush(hpxyz(0.350926,-0.441337,1.148010)); + hpcpush(hpxyz(0.036765,-0.163958,1.014019)); + hpcpush(hpxyz(-0.126252,-0.549535,1.148010)); + hpcpush(hpxyz(-0.105265,-0.130970,1.014019)); + hpcpush(hpxyz(-0.508361,-0.243921,1.148010)); + hpcpush(hpxyz(-0.168028,0.000641,1.014019)); + hpcpush(hpxyz(-0.507663,0.245370,1.148010)); + hpcpush(hpxyz(-0.104263,0.131769,1.014019)); + hpcpush(hpxyz(-0.124685,0.549893,1.148010)); + hpcpush(hpxyz(0.038015,0.163673,1.014019)); + hpcpush(hpxyz(0.352184,0.440335,1.148010)); + hpcpush(hpxyz(0.151666,0.072327,1.014019)); + hpcpush(hpxyz(0.563851,-0.000804,1.148010)); + + bshape(shMirror, 13); + for(int t=0; t<=6; t++) hpcpush(ddi(7 + t*14, hexf*.7) * C0); + + bshape(shWall[0], 13); + for(int t=0; t<=6; t++) { + hpcpush(ddi(7 + t*14, hexf*.8) * C0); + hpcpush(ddi(14 + t*14, hexf*.2) * C0); + } + + bshape(shWall[1], 13); + for(int t=0; t<=7; t++) hpcpush(ddi(t*36, hexf*.94) * C0); + + bshape(shCross, 13); + for(int i=0; i<=84; i+=7) + hpcpush(ddi(i, hexf * (i%3 ? 0.8 : 0.3)) * C0); + + // items + + bshape(shDaisy, 21); + for(int t=0; t<=6; t++) { + hpcpush(ddi(t*14, hexf*.8*3/4) * C0); + hpcpush(ddi(t*14+7, hexf*-.5*3/4) * C0); + } + hpcpush(ddi(0, hexf*.6) * C0); + + bshape(shTriangle, 21); + for(int t=0; t<=4; t++) { + hpcpush(ddi(t*28, hexf*.5) * C0); + } + + bshape(shGem[0], 21); + for(int t=0; t<=6; t++) { + hpcpush(ddi(7 + t*14, hexf*.4) * C0); + hpcpush(ddi(14 + t*14, hexf*.1) * C0); + } + + bshape(shGem[1], 21); + for(int t=0; t<=7; t++) hpcpush(ddi(t*36, hexf*.5) * C0); + + bshape(shStar, 21); + for(int t=0; t<84; t+=6) { + hpcpush(ddi(t, hexf*.2) * C0); + hpcpush(ddi(t+3, hexf*.6) * C0); + } + + bshape(shDisk, 21); + for(int i=0; i<=84; i+=3) + hpcpush(ddi(i, crossf * .2) * C0); + + bshape(shRing, 21); + for(int i=0; i<=84; i+=3) + hpcpush(ddi(i, crossf * .25) * C0); + for(int i=84; i>=0; i--) + hpcpush(ddi(i, crossf * .30) * C0); + hpcpush(ddi(0, crossf * .25) * C0); + + bshape(shNecro, 21); + hpcpush(hpxyz(-0.280120,0.002558,1.038496)); + hpcpush(hpxyz(-0.252806,0.037921,1.032157)); + hpcpush(hpxyz(-0.063204,0.010733,1.002053)); + hpcpush(hpxyz(0.000000,0.061995,1.001920)); + hpcpush(hpxyz(0.057203,0.013109,1.001721)); + hpcpush(hpxyz(0.155766,0.023121,1.012323)); + hpcpush(hpxyz(0.174234,0.055215,1.016566)); + hpcpush(hpxyz(0.256152,0.057064,1.033862)); + hpcpush(hpxyz(0.286380,0.030821,1.040655)); + hpcpush(hpxyz(0.251170,0.025243,1.031370)); + hpcpush(hpxyz(0.227431,0.033740,1.026091)); + hpcpush(hpxyz(0.210837,0.017363,1.022132)); + hpcpush(hpxyz(0.227179,0.007489,1.025508)); + hpcpush(hpxyz(0.245429,0.020138,1.029874)); + hpcpush(hpxyz(0.286335,0.028248,1.040570)); + hpcpush(hpxyz(0.289108,0.001285,1.040954)); + hpcpush(hpxyz(0.189404,0.003690,1.017786)); + hpcpush(hpxyz(0.186892,0.025821,1.017642)); + hpcpush(hpxyz(0.176349,0.017145,1.015575)); + hpcpush(hpxyz(0.184160,0.011050,1.016876)); + hpcpush(hpxyz(0.177605,0.006124,1.015668)); + hpcpush(hpxyz(0.184138,0.001228,1.016813)); + hpcpush(hpxyz(0.184138,-0.001228,1.016813)); + hpcpush(hpxyz(0.177605,-0.006124,1.015668)); + hpcpush(hpxyz(0.184160,-0.011050,1.016876)); + hpcpush(hpxyz(0.176349,-0.017145,1.015575)); + hpcpush(hpxyz(0.186892,-0.025821,1.017642)); + hpcpush(hpxyz(0.189404,-0.003690,1.017786)); + hpcpush(hpxyz(0.289108,-0.001285,1.040954)); + hpcpush(hpxyz(0.286335,-0.028248,1.040570)); + hpcpush(hpxyz(0.245429,-0.020138,1.029874)); + hpcpush(hpxyz(0.227179,-0.007489,1.025508)); + hpcpush(hpxyz(0.210837,-0.017363,1.022132)); + hpcpush(hpxyz(0.227431,-0.033740,1.026091)); + hpcpush(hpxyz(0.251170,-0.025243,1.031370)); + hpcpush(hpxyz(0.286380,-0.030821,1.040655)); + hpcpush(hpxyz(0.256152,-0.057064,1.033862)); + hpcpush(hpxyz(0.174234,-0.055215,1.016566)); + hpcpush(hpxyz(0.155766,-0.023121,1.012323)); + hpcpush(hpxyz(0.057203,-0.013109,1.001721)); + hpcpush(hpxyz(0.000000,-0.061995,1.001920)); + hpcpush(hpxyz(-0.063204,-0.010733,1.002053)); + hpcpush(hpxyz(-0.252806,-0.037921,1.032157)); + hpcpush(hpxyz(-0.280120,-0.002558,1.038496)); + hpcpush(hpxyz(-0.280120,0.002558,1.038496)); + + bshape(shStatue, 21); + hpcpush(hpxyz(-0.047663,0.032172,1.001652)); + hpcpush(hpxyz(-0.047670,0.034561,1.001732)); + hpcpush(hpxyz(-0.054881,0.039371,1.002278)); + hpcpush(hpxyz(-0.080231,0.043109,1.004139)); + hpcpush(hpxyz(-0.103440,0.045706,1.006374)); + hpcpush(hpxyz(-0.148323,0.042552,1.011835)); + hpcpush(hpxyz(-0.188278,0.031995,1.018073)); + hpcpush(hpxyz(-0.239693,0.002510,1.028328)); + hpcpush(hpxyz(-0.257087,-0.036727,1.033171)); + hpcpush(hpxyz(-0.283314,-0.026921,1.039708)); + hpcpush(hpxyz(-0.290985,0.034764,1.042056)); + hpcpush(hpxyz(-0.262852,0.081663,1.037189)); + hpcpush(hpxyz(-0.198209,0.104714,1.024818)); + hpcpush(hpxyz(-0.140842,0.107775,1.015604)); + hpcpush(hpxyz(-0.088218,0.099094,1.008763)); + hpcpush(hpxyz(-0.057645,0.088869,1.005595)); + hpcpush(hpxyz(-0.035877,0.075342,1.003476)); + hpcpush(hpxyz(-0.023854,0.060828,1.002132)); + hpcpush(hpxyz(-0.022642,0.053625,1.001693)); + hpcpush(hpxyz(-0.011901,0.044034,1.001040)); + hpcpush(hpxyz(-0.007144,0.050008,1.001275)); + hpcpush(hpxyz(-0.010953,0.056452,1.001652)); + hpcpush(hpxyz(-0.009270,0.058147,1.001732)); + hpcpush(hpxyz(-0.010967,0.066646,1.002278)); + hpcpush(hpxyz(-0.026249,0.087215,1.004139)); + hpcpush(hpxyz(-0.040824,0.105462,1.006374)); + hpcpush(hpxyz(-0.074791,0.134969,1.011835)); + hpcpush(hpxyz(-0.110509,0.155757,1.018073)); + hpcpush(hpxyz(-0.167714,0.171263,1.028328)); + hpcpush(hpxyz(-0.207758,0.155818,1.033171)); + hpcpush(hpxyz(-0.219370,0.181297,1.039708)); + hpcpush(hpxyz(-0.181176,0.230339,1.042056)); + hpcpush(hpxyz(-0.128120,0.243609,1.037189)); + hpcpush(hpxyz(-0.066111,0.214199,1.024818)); + hpcpush(hpxyz(-0.023382,0.175799,1.015604)); + hpcpush(hpxyz(0.007691,0.132449,1.008763)); + hpcpush(hpxyz(0.022079,0.103601,1.005595)); + hpcpush(hpxyz(0.027906,0.078644,1.003476)); + hpcpush(hpxyz(0.026145,0.059880,1.002132)); + hpcpush(hpxyz(0.021909,0.053929,1.001693)); + hpcpush(hpxyz(0.022722,0.039552,1.001040)); + hpcpush(hpxyz(0.030310,0.040413,1.001275)); + hpcpush(hpxyz(0.032172,0.047663,1.001652)); + hpcpush(hpxyz(0.034561,0.047670,1.001732)); + hpcpush(hpxyz(0.039371,0.054881,1.002278)); + hpcpush(hpxyz(0.043109,0.080231,1.004139)); + hpcpush(hpxyz(0.045706,0.103440,1.006374)); + hpcpush(hpxyz(0.042552,0.148323,1.011835)); + hpcpush(hpxyz(0.031995,0.188278,1.018073)); + hpcpush(hpxyz(0.002510,0.239693,1.028328)); + hpcpush(hpxyz(-0.036727,0.257087,1.033171)); + hpcpush(hpxyz(-0.026921,0.283314,1.039708)); + hpcpush(hpxyz(0.034764,0.290985,1.042056)); + hpcpush(hpxyz(0.081663,0.262852,1.037189)); + hpcpush(hpxyz(0.104714,0.198209,1.024818)); + hpcpush(hpxyz(0.107775,0.140842,1.015604)); + hpcpush(hpxyz(0.099094,0.088218,1.008763)); + hpcpush(hpxyz(0.088869,0.057645,1.005595)); + hpcpush(hpxyz(0.075342,0.035877,1.003476)); + hpcpush(hpxyz(0.060828,0.023854,1.002132)); + hpcpush(hpxyz(0.053625,0.022642,1.001693)); + hpcpush(hpxyz(0.044034,0.011901,1.001040)); + hpcpush(hpxyz(0.050008,0.007144,1.001275)); + hpcpush(hpxyz(0.056452,0.010953,1.001652)); + hpcpush(hpxyz(0.058147,0.009270,1.001732)); + hpcpush(hpxyz(0.066646,0.010967,1.002278)); + hpcpush(hpxyz(0.087215,0.026249,1.004139)); + hpcpush(hpxyz(0.105462,0.040824,1.006374)); + hpcpush(hpxyz(0.134969,0.074791,1.011835)); + hpcpush(hpxyz(0.155757,0.110509,1.018073)); + hpcpush(hpxyz(0.171263,0.167714,1.028328)); + hpcpush(hpxyz(0.155818,0.207758,1.033171)); + hpcpush(hpxyz(0.181297,0.219370,1.039708)); + hpcpush(hpxyz(0.230339,0.181176,1.042056)); + hpcpush(hpxyz(0.243609,0.128120,1.037189)); + hpcpush(hpxyz(0.214199,0.066111,1.024818)); + hpcpush(hpxyz(0.175799,0.023382,1.015604)); + hpcpush(hpxyz(0.132449,-0.007691,1.008763)); + hpcpush(hpxyz(0.103601,-0.022079,1.005595)); + hpcpush(hpxyz(0.078644,-0.027906,1.003476)); + hpcpush(hpxyz(0.059880,-0.026145,1.002132)); + hpcpush(hpxyz(0.053929,-0.021909,1.001693)); + hpcpush(hpxyz(0.039552,-0.022722,1.001040)); + hpcpush(hpxyz(0.040413,-0.030310,1.001275)); + hpcpush(hpxyz(0.047663,-0.032172,1.001652)); + hpcpush(hpxyz(0.047670,-0.034561,1.001732)); + hpcpush(hpxyz(0.054881,-0.039371,1.002278)); + hpcpush(hpxyz(0.080231,-0.043109,1.004139)); + hpcpush(hpxyz(0.103440,-0.045706,1.006374)); + hpcpush(hpxyz(0.148323,-0.042552,1.011835)); + hpcpush(hpxyz(0.188278,-0.031995,1.018073)); + hpcpush(hpxyz(0.239693,-0.002510,1.028328)); + hpcpush(hpxyz(0.257087,0.036727,1.033171)); + hpcpush(hpxyz(0.283314,0.026921,1.039708)); + hpcpush(hpxyz(0.290985,-0.034764,1.042056)); + hpcpush(hpxyz(0.262852,-0.081663,1.037189)); + hpcpush(hpxyz(0.198209,-0.104714,1.024818)); + hpcpush(hpxyz(0.140842,-0.107775,1.015604)); + hpcpush(hpxyz(0.088218,-0.099094,1.008763)); + hpcpush(hpxyz(0.057645,-0.088869,1.005595)); + hpcpush(hpxyz(0.035877,-0.075342,1.003476)); + hpcpush(hpxyz(0.023854,-0.060828,1.002132)); + hpcpush(hpxyz(0.022642,-0.053625,1.001693)); + hpcpush(hpxyz(0.011901,-0.044034,1.001040)); + hpcpush(hpxyz(0.007144,-0.050008,1.001275)); + hpcpush(hpxyz(0.010953,-0.056452,1.001652)); + hpcpush(hpxyz(0.009270,-0.058147,1.001732)); + hpcpush(hpxyz(0.010967,-0.066646,1.002278)); + hpcpush(hpxyz(0.026249,-0.087215,1.004139)); + hpcpush(hpxyz(0.040824,-0.105462,1.006374)); + hpcpush(hpxyz(0.074791,-0.134969,1.011835)); + hpcpush(hpxyz(0.110509,-0.155757,1.018073)); + hpcpush(hpxyz(0.167714,-0.171263,1.028328)); + hpcpush(hpxyz(0.207758,-0.155818,1.033171)); + hpcpush(hpxyz(0.219370,-0.181297,1.039708)); + hpcpush(hpxyz(0.181176,-0.230339,1.042056)); + hpcpush(hpxyz(0.128120,-0.243609,1.037189)); + hpcpush(hpxyz(0.066111,-0.214199,1.024818)); + hpcpush(hpxyz(0.023382,-0.175799,1.015604)); + hpcpush(hpxyz(-0.007691,-0.132449,1.008763)); + hpcpush(hpxyz(-0.022079,-0.103601,1.005595)); + hpcpush(hpxyz(-0.027906,-0.078644,1.003476)); + hpcpush(hpxyz(-0.026145,-0.059880,1.002132)); + hpcpush(hpxyz(-0.021909,-0.053929,1.001693)); + hpcpush(hpxyz(-0.022722,-0.039552,1.001040)); + hpcpush(hpxyz(-0.030310,-0.040413,1.001275)); + hpcpush(hpxyz(-0.032172,-0.047663,1.001652)); + hpcpush(hpxyz(-0.034561,-0.047670,1.001732)); + hpcpush(hpxyz(-0.039371,-0.054881,1.002278)); + hpcpush(hpxyz(-0.043109,-0.080231,1.004139)); + hpcpush(hpxyz(-0.045706,-0.103440,1.006374)); + hpcpush(hpxyz(-0.042552,-0.148323,1.011835)); + hpcpush(hpxyz(-0.031995,-0.188278,1.018073)); + hpcpush(hpxyz(-0.002510,-0.239693,1.028328)); + hpcpush(hpxyz(0.036727,-0.257087,1.033171)); + hpcpush(hpxyz(0.026921,-0.283314,1.039708)); + hpcpush(hpxyz(-0.034764,-0.290985,1.042056)); + hpcpush(hpxyz(-0.081663,-0.262852,1.037189)); + hpcpush(hpxyz(-0.104714,-0.198209,1.024818)); + hpcpush(hpxyz(-0.107775,-0.140842,1.015604)); + hpcpush(hpxyz(-0.099094,-0.088218,1.008763)); + hpcpush(hpxyz(-0.088869,-0.057645,1.005595)); + hpcpush(hpxyz(-0.075342,-0.035877,1.003476)); + hpcpush(hpxyz(-0.060828,-0.023854,1.002132)); + hpcpush(hpxyz(-0.053625,-0.022642,1.001693)); + hpcpush(hpxyz(-0.044034,-0.011901,1.001040)); + hpcpush(hpxyz(-0.050008,-0.007144,1.001275)); + hpcpush(hpxyz(-0.056452,-0.010953,1.001652)); + hpcpush(hpxyz(-0.058147,-0.009270,1.001732)); + hpcpush(hpxyz(-0.066646,-0.010967,1.002278)); + hpcpush(hpxyz(-0.087215,-0.026249,1.004139)); + hpcpush(hpxyz(-0.105462,-0.040824,1.006374)); + hpcpush(hpxyz(-0.134969,-0.074791,1.011835)); + hpcpush(hpxyz(-0.155757,-0.110509,1.018073)); + hpcpush(hpxyz(-0.171263,-0.167714,1.028328)); + hpcpush(hpxyz(-0.155818,-0.207758,1.033171)); + hpcpush(hpxyz(-0.181297,-0.219370,1.039708)); + hpcpush(hpxyz(-0.230339,-0.181176,1.042056)); + hpcpush(hpxyz(-0.243609,-0.128120,1.037189)); + hpcpush(hpxyz(-0.214199,-0.066111,1.024818)); + hpcpush(hpxyz(-0.175799,-0.023382,1.015604)); + hpcpush(hpxyz(-0.132449,0.007691,1.008763)); + hpcpush(hpxyz(-0.103601,0.022079,1.005595)); + hpcpush(hpxyz(-0.078644,0.027906,1.003476)); + hpcpush(hpxyz(-0.059880,0.026145,1.002132)); + hpcpush(hpxyz(-0.053929,0.021909,1.001693)); + hpcpush(hpxyz(-0.039552,0.022722,1.001040)); + hpcpush(hpxyz(-0.040413,0.030310,1.001275)); + hpcpush(hpxyz(-0.047663,0.032172,1.001652)); + + bshape(shBook, 21); + hpcpush(hpxyz(-0.123296,-0.203475,1.027912)); + hpcpush(hpxyz( 0.123296,-0.203475,1.027912)); + hpcpush(hpxyz( 0.123296, 0.203475,1.027912)); + hpcpush(hpxyz(-0.123296, 0.203475,1.027912)); + hpcpush(hpxyz(-0.123296,-0.203475,1.027912)); + + bshape(shBookCover, 22); + hpcpush(hpxyz(0.018255,-0.016768,1.000307)); + hpcpush(hpxyz(0.010865,-0.065298,1.002189)); + hpcpush(hpxyz(0.044639,-0.075918,1.003871)); + hpcpush(hpxyz(0.027526,-0.106818,1.006065)); + hpcpush(hpxyz(-0.029540,-0.088203,1.004317)); + hpcpush(hpxyz(-0.023649,-0.007425,1.000307)); + hpcpush(hpxyz(-0.061983,0.023240,1.002189)); + hpcpush(hpxyz(-0.088066,-0.000700,1.003871)); + hpcpush(hpxyz(-0.106270,0.029571,1.006065)); + hpcpush(hpxyz(-0.061616,0.069684,1.004317)); + hpcpush(hpxyz(0.005394,0.024193,1.000307)); + hpcpush(hpxyz(0.051117,0.042059,1.002189)); + hpcpush(hpxyz(0.043427,0.076618,1.003871)); + hpcpush(hpxyz(0.078744,0.077247,1.006065)); + hpcpush(hpxyz(0.091156,0.018519,1.004317)); + hpcpush(hpxyz(0.018255,-0.016768,1.000307)); + + bshape(shGrail, 21); + hpcpush(hpxyz(-0.154537,0.122394,1.019246)); + hpcpush(hpxyz(-0.142973,0.123252,1.017660)); + hpcpush(hpxyz(-0.138296,0.095461,1.014021)); + hpcpush(hpxyz(-0.123926,0.072898,1.010283)); + hpcpush(hpxyz(-0.107625,0.065300,1.007892)); + hpcpush(hpxyz(-0.067188,0.057589,1.003908)); + hpcpush(hpxyz(-0.040655,0.052612,1.002208)); + hpcpush(hpxyz(-0.037133,0.069475,1.003098)); + hpcpush(hpxyz(-0.021657,0.101065,1.005327)); + hpcpush(hpxyz(0.003631,0.129510,1.008358)); + hpcpush(hpxyz(0.040272,0.153766,1.012554)); + hpcpush(hpxyz(0.087340,0.161149,1.016660)); + hpcpush(hpxyz(0.127500,0.154732,1.019901)); + hpcpush(hpxyz(0.161853,0.141932,1.022908)); + hpcpush(hpxyz(0.184896,0.152194,1.028275)); + hpcpush(hpxyz(0.189249,0.157707,1.029896)); + hpcpush(hpxyz(0.189249,-0.157707,1.029896)); + hpcpush(hpxyz(0.184896,-0.152194,1.028275)); + hpcpush(hpxyz(0.161853,-0.141932,1.022908)); + hpcpush(hpxyz(0.127500,-0.154732,1.019901)); + hpcpush(hpxyz(0.087340,-0.161149,1.016660)); + hpcpush(hpxyz(0.040272,-0.153766,1.012554)); + hpcpush(hpxyz(0.003631,-0.129510,1.008358)); + hpcpush(hpxyz(-0.021657,-0.101065,1.005327)); + hpcpush(hpxyz(-0.037133,-0.069475,1.003098)); + hpcpush(hpxyz(-0.040655,-0.052612,1.002208)); + hpcpush(hpxyz(-0.067188,-0.057589,1.003908)); + hpcpush(hpxyz(-0.107625,-0.065300,1.007892)); + hpcpush(hpxyz(-0.123926,-0.072898,1.010283)); + hpcpush(hpxyz(-0.138296,-0.095461,1.014021)); + hpcpush(hpxyz(-0.142973,-0.123252,1.017660)); + hpcpush(hpxyz(-0.154537,-0.122394,1.019246)); + hpcpush(hpxyz(-0.154537,0.122394,1.019246)); + + bshape(shKey, 21); + hpcpush(hpxyz(-0.280212,-0.017913,1.038672)); + hpcpush(hpxyz(-0.279685,0.060299,1.040125)); + hpcpush(hpxyz(-0.258790,0.115302,1.039359)); + hpcpush(hpxyz(-0.228319,0.104699,1.031063)); + hpcpush(hpxyz(-0.239075,0.056623,1.029739)); + hpcpush(hpxyz(-0.213944,0.046023,1.023665)); + hpcpush(hpxyz(-0.200310,0.089579,1.023791)); + hpcpush(hpxyz(-0.168273,0.078609,1.017101)); + hpcpush(hpxyz(-0.179201,0.040504,1.016737)); + hpcpush(hpxyz(-0.150719,0.029171,1.011715)); + hpcpush(hpxyz(-0.146064,0.060860,1.012442)); + hpcpush(hpxyz(-0.115859,0.053102,1.008089)); + hpcpush(hpxyz(-0.119288,0.019279,1.007274)); + hpcpush(hpxyz(-0.087371,0.011969,1.003881)); + hpcpush(hpxyz(-0.080285,0.050328,1.004479)); + hpcpush(hpxyz(-0.068304,0.065908,1.004495)); + hpcpush(hpxyz(-0.052728,0.079091,1.004508)); + hpcpush(hpxyz(-0.033525,0.083811,1.004066)); + hpcpush(hpxyz(-0.007181,0.087363,1.003835)); + hpcpush(hpxyz(0.025157,0.089847,1.004343)); + hpcpush(hpxyz(0.044329,0.082667,1.004390)); + hpcpush(hpxyz(0.061077,0.068263,1.004186)); + hpcpush(hpxyz(0.074262,0.055098,1.004266)); + hpcpush(hpxyz(0.088682,0.034754,1.004526)); + hpcpush(hpxyz(0.093450,0.008387,1.004392)); + hpcpush(hpxyz(0.092228,-0.005989,1.004262)); + hpcpush(hpxyz(0.092278,-0.023968,1.004535)); + hpcpush(hpxyz(0.085107,-0.045550,1.004648)); + hpcpush(hpxyz(0.070661,-0.058685,1.004210)); + hpcpush(hpxyz(0.045297,-0.040529,1.001846)); + hpcpush(hpxyz(0.057205,-0.014301,1.001737)); + hpcpush(hpxyz(0.057207,0.015494,1.001755)); + hpcpush(hpxyz(0.041704,0.039321,1.001641)); + hpcpush(hpxyz(0.023823,0.048837,1.001475)); + hpcpush(hpxyz(0.003575,0.058394,1.001710)); + hpcpush(hpxyz(-0.021441,0.050029,1.001480)); + hpcpush(hpxyz(-0.047692,0.040538,1.001957)); + hpcpush(hpxyz(-0.054813,0.017874,1.001661)); + hpcpush(hpxyz(-0.054802,-0.010722,1.001558)); + hpcpush(hpxyz(-0.036924,-0.039306,1.001453)); + hpcpush(hpxyz(-0.020254,-0.052421,1.001578)); + hpcpush(hpxyz(0.011915,-0.056002,1.001638)); + hpcpush(hpxyz(0.034561,-0.047670,1.001732)); + hpcpush(hpxyz(0.045297,-0.040529,1.001846)); + hpcpush(hpxyz(0.070661,-0.058685,1.004210)); + hpcpush(hpxyz(0.055051,-0.068215,1.003835)); + hpcpush(hpxyz(0.033505,-0.080172,1.003768)); + hpcpush(hpxyz(0.011971,-0.088587,1.003988)); + hpcpush(hpxyz(-0.010772,-0.087369,1.003867)); + hpcpush(hpxyz(-0.035904,-0.080185,1.003852)); + hpcpush(hpxyz(-0.061039,-0.063432,1.003867)); + hpcpush(hpxyz(-0.071750,-0.041854,1.003444)); + hpcpush(hpxyz(-0.082525,-0.015548,1.003520)); + hpcpush(hpxyz(-0.280212,-0.017913,1.038672)); + hpcpush(hpxyz(-0.280212,-0.017913,1.038672)); + + // monsters + + bshape(shTentacleX, 31); + drawTentacle(shTentacleX, crossf * .25, crossf * .1, 10); + + bshape(shBranch, 32); + hpcpush(ddi(21, crossf/5) * C0); + hpcpush(ddi(21, -crossf/5) * C0); + hpcpush(ddi(21, -crossf/5) * ddi(0, crossf) * C0); + hpcpush(ddi(21, crossf/5) * ddi(0, crossf) * C0); + + bshape(shIBranch, 32); + drawTentacle(shIBranch, crossf * .1, crossf * .2, 5); + + bshape(shTentacle, 32); + drawTentacle(shTentacle, crossf * .2, crossf * .1, 10); + + shJoint = shDisk; shJoint.prio = 33; + + bshape(shGhost, 33); + hpcpush(hpxyz(-0.312167,0.001301,1.047592)); + hpcpush(hpxyz(-0.185499,0.015970,1.017185)); + hpcpush(hpxyz(-0.273136,0.038290,1.037338)); + hpcpush(hpxyz(-0.184484,0.043046,1.017786)); + hpcpush(hpxyz(-0.296331,0.093578,1.047172)); + hpcpush(hpxyz(-0.174561,0.070070,1.017537)); + hpcpush(hpxyz(-0.222751,0.104454,1.029820)); + hpcpush(hpxyz(-0.162371,0.098407,1.017864)); + hpcpush(hpxyz(-0.272077,0.156217,1.048060)); + hpcpush(hpxyz(-0.140182,0.126656,1.017690)); + hpcpush(hpxyz(-0.161729,0.148045,1.023755)); + hpcpush(hpxyz(-0.119271,0.146323,1.017662)); + hpcpush(hpxyz(-0.231927,0.213686,1.048548)); + hpcpush(hpxyz(-0.001244,0.218928,1.023685)); + hpcpush(hpxyz(0.016184,0.220354,1.024118)); + hpcpush(hpxyz(0.031094,0.216414,1.023622)); + hpcpush(hpxyz(0.045998,0.212585,1.023381)); + hpcpush(hpxyz(0.064748,0.211675,1.024206)); + hpcpush(hpxyz(0.079530,0.201310,1.023157)); + hpcpush(hpxyz(0.094597,0.199151,1.024016)); + hpcpush(hpxyz(0.110770,0.190424,1.023978)); + hpcpush(hpxyz(0.123174,0.181651,1.023801)); + hpcpush(hpxyz(0.132996,0.171528,1.023284)); + hpcpush(hpxyz(0.149284,0.160480,1.023738)); + hpcpush(hpxyz(0.156499,0.147805,1.022907)); + hpcpush(hpxyz(0.171645,0.135575,1.023642)); + hpcpush(hpxyz(0.180157,0.119276,1.023075)); + hpcpush(hpxyz(0.188931,0.106895,1.023290)); + hpcpush(hpxyz(0.197759,0.093283,1.023626)); + hpcpush(hpxyz(0.201351,0.080789,1.023264)); + hpcpush(hpxyz(0.209030,0.067188,1.023820)); + hpcpush(hpxyz(0.212718,0.052246,1.023708)); + hpcpush(hpxyz(0.215145,0.037308,1.023562)); + hpcpush(hpxyz(0.217714,0.026126,1.023759)); + hpcpush(hpxyz(0.217612,0.014922,1.023512)); + hpcpush(hpxyz(0.217612,-0.014922,1.023512)); + hpcpush(hpxyz(0.217714,-0.026126,1.023759)); + hpcpush(hpxyz(0.215145,-0.037308,1.023562)); + hpcpush(hpxyz(0.212718,-0.052246,1.023708)); + hpcpush(hpxyz(0.209030,-0.067188,1.023820)); + hpcpush(hpxyz(0.201351,-0.080789,1.023264)); + hpcpush(hpxyz(0.197759,-0.093283,1.023626)); + hpcpush(hpxyz(0.188931,-0.106895,1.023290)); + hpcpush(hpxyz(0.180157,-0.119276,1.023075)); + hpcpush(hpxyz(0.171645,-0.135575,1.023642)); + hpcpush(hpxyz(0.156499,-0.147805,1.022907)); + hpcpush(hpxyz(0.149284,-0.160480,1.023738)); + hpcpush(hpxyz(0.132996,-0.171528,1.023284)); + hpcpush(hpxyz(0.123174,-0.181651,1.023801)); + hpcpush(hpxyz(0.110770,-0.190424,1.023978)); + hpcpush(hpxyz(0.094597,-0.199151,1.024016)); + hpcpush(hpxyz(0.079530,-0.201310,1.023157)); + hpcpush(hpxyz(0.064748,-0.211675,1.024206)); + hpcpush(hpxyz(0.045998,-0.212585,1.023381)); + hpcpush(hpxyz(0.031094,-0.216414,1.023622)); + hpcpush(hpxyz(0.016184,-0.220354,1.024118)); + hpcpush(hpxyz(-0.001244,-0.218928,1.023685)); + hpcpush(hpxyz(-0.231927,-0.213686,1.048548)); + hpcpush(hpxyz(-0.119271,-0.146323,1.017662)); + hpcpush(hpxyz(-0.161729,-0.148045,1.023755)); + hpcpush(hpxyz(-0.140182,-0.126656,1.017690)); + hpcpush(hpxyz(-0.272077,-0.156217,1.048060)); + hpcpush(hpxyz(-0.162371,-0.098407,1.017864)); + hpcpush(hpxyz(-0.222751,-0.104454,1.029820)); + hpcpush(hpxyz(-0.174561,-0.070070,1.017537)); + hpcpush(hpxyz(-0.296331,-0.093578,1.047172)); + hpcpush(hpxyz(-0.184484,-0.043046,1.017786)); + hpcpush(hpxyz(-0.273136,-0.038290,1.037338)); + hpcpush(hpxyz(-0.185499,-0.015970,1.017185)); + hpcpush(hpxyz(-0.312167,-0.001301,1.047592)); + hpcpush(hpxyz(-0.312167,0.001301,1.047592)); + + bshape(shILeaf[0], 33); + for(int t=0; t<=6; t++) { + hpcpush(ddi(7 + t*14, hexf*.7) * C0); + hpcpush(ddi(14 + t*14, hexf*.15) * C0); + } + + bshape(shILeaf[1], 33); + for(int t=0; t<=7; t++) hpcpush(ddi(t*36, hexf*.8) * C0); + + bshape(shWolf, 33); + hpcpush(hpxyz(-0.310601,0.000000,1.047126)); + hpcpush(hpxyz(-0.158251,0.009739,1.012491)); + hpcpush(hpxyz(-0.149626,0.045009,1.012133)); + hpcpush(hpxyz(-0.173168,0.066320,1.017047)); + hpcpush(hpxyz(-0.250414,0.056912,1.032447)); + hpcpush(hpxyz(-0.242122,0.064314,1.030902)); + hpcpush(hpxyz(-0.253563,0.065926,1.033751)); + hpcpush(hpxyz(-0.241104,0.075740,1.031440)); + hpcpush(hpxyz(-0.249897,0.082453,1.034044)); + hpcpush(hpxyz(-0.237118,0.081982,1.030993)); + hpcpush(hpxyz(-0.246310,0.097762,1.034517)); + hpcpush(hpxyz(-0.230366,0.088118,1.029968)); + hpcpush(hpxyz(-0.210870,0.082352,1.025304)); + hpcpush(hpxyz(-0.194727,0.083100,1.022166)); + hpcpush(hpxyz(-0.180298,0.087679,1.019899)); + hpcpush(hpxyz(-0.162032,0.087154,1.016784)); + hpcpush(hpxyz(-0.135091,0.081542,1.012373)); + hpcpush(hpxyz(-0.116083,0.068924,1.009072)); + hpcpush(hpxyz(-0.106144,0.066340,1.007803)); + hpcpush(hpxyz(-0.084057,0.063643,1.005543)); + hpcpush(hpxyz(-0.061108,0.071892,1.004441)); + hpcpush(hpxyz(-0.044295,0.077815,1.004001)); + hpcpush(hpxyz(-0.021516,0.077698,1.003245)); + hpcpush(hpxyz(0.000000,0.078872,1.003106)); + hpcpush(hpxyz(0.025203,0.099613,1.005265)); + hpcpush(hpxyz(0.040964,0.113252,1.007226)); + hpcpush(hpxyz(0.067885,0.127285,1.010351)); + hpcpush(hpxyz(0.086481,0.135203,1.012798)); + hpcpush(hpxyz(0.104129,0.144556,1.015746)); + hpcpush(hpxyz(0.097579,0.132951,1.013508)); + hpcpush(hpxyz(0.112604,0.134635,1.015286)); + hpcpush(hpxyz(0.098603,0.124167,1.012492)); + hpcpush(hpxyz(0.118341,0.115901,1.013626)); + hpcpush(hpxyz(0.094688,0.115325,1.011072)); + hpcpush(hpxyz(0.079806,0.108826,1.009065)); + hpcpush(hpxyz(0.065011,0.097516,1.006845)); + hpcpush(hpxyz(0.053964,0.082746,1.004868)); + hpcpush(hpxyz(0.049028,0.066966,1.003438)); + hpcpush(hpxyz(0.045353,0.053708,1.002468)); + hpcpush(hpxyz(0.046494,0.040534,1.001901)); + hpcpush(hpxyz(0.051260,0.033378,1.001869)); + hpcpush(hpxyz(0.059646,0.029823,1.002221)); + hpcpush(hpxyz(0.069275,0.029860,1.002841)); + hpcpush(hpxyz(0.077732,0.029897,1.003462)); + hpcpush(hpxyz(0.081360,0.028715,1.003715)); + hpcpush(hpxyz(0.092268,0.021569,1.004479)); + hpcpush(hpxyz(0.102040,0.020408,1.005400)); + hpcpush(hpxyz(0.108180,0.020434,1.006042)); + hpcpush(hpxyz(0.123078,0.030166,1.007997)); + hpcpush(hpxyz(0.100952,0.042063,1.005963)); + hpcpush(hpxyz(0.125691,0.043508,1.008807)); + hpcpush(hpxyz(0.144550,0.044944,1.011393)); + hpcpush(hpxyz(0.154674,0.041409,1.012738)); + hpcpush(hpxyz(0.177755,0.029421,1.016102)); + hpcpush(hpxyz(0.154429,0.012160,1.011927)); + hpcpush(hpxyz(0.146841,0.019417,1.010910)); + hpcpush(hpxyz(0.132964,0.013296,1.008889)); + hpcpush(hpxyz(0.143007,0.009695,1.010220)); + hpcpush(hpxyz(0.154429,0.012160,1.011927)); + hpcpush(hpxyz(0.177755,0.029421,1.016102)); + hpcpush(hpxyz(0.184262,0.025797,1.017162)); + hpcpush(hpxyz(0.185576,0.025809,1.017401)); + hpcpush(hpxyz(0.190852,0.025857,1.018378)); + hpcpush(hpxyz(0.194828,0.025895,1.019131)); + hpcpush(hpxyz(0.201483,0.024722,1.020395)); + hpcpush(hpxyz(0.205462,0.019804,1.021081)); + hpcpush(hpxyz(0.210828,0.016122,1.022110)); + hpcpush(hpxyz(0.210793,0.009920,1.022024)); + hpcpush(hpxyz(0.217604,0.013678,1.023493)); + hpcpush(hpxyz(0.208083,0.007432,1.021447)); + hpcpush(hpxyz(0.208083,-0.007432,1.021447)); + hpcpush(hpxyz(0.217604,-0.013678,1.023493)); + hpcpush(hpxyz(0.210793,-0.009920,1.022024)); + hpcpush(hpxyz(0.210828,-0.016122,1.022110)); + hpcpush(hpxyz(0.205462,-0.019804,1.021081)); + hpcpush(hpxyz(0.201483,-0.024722,1.020395)); + hpcpush(hpxyz(0.194828,-0.025895,1.019131)); + hpcpush(hpxyz(0.190852,-0.025857,1.018378)); + hpcpush(hpxyz(0.185576,-0.025809,1.017401)); + hpcpush(hpxyz(0.184262,-0.025797,1.017162)); + hpcpush(hpxyz(0.177755,-0.029421,1.016102)); + hpcpush(hpxyz(0.154429,-0.012160,1.011927)); + hpcpush(hpxyz(0.143007,-0.009695,1.010220)); + hpcpush(hpxyz(0.132964,-0.013296,1.008889)); + hpcpush(hpxyz(0.146841,-0.019417,1.010910)); + hpcpush(hpxyz(0.154429,-0.012160,1.011927)); + hpcpush(hpxyz(0.177755,-0.029421,1.016102)); + hpcpush(hpxyz(0.154674,-0.041409,1.012738)); + hpcpush(hpxyz(0.144550,-0.044944,1.011393)); + hpcpush(hpxyz(0.125691,-0.043508,1.008807)); + hpcpush(hpxyz(0.100952,-0.042063,1.005963)); + hpcpush(hpxyz(0.123078,-0.030166,1.007997)); + hpcpush(hpxyz(0.108180,-0.020434,1.006042)); + hpcpush(hpxyz(0.102040,-0.020408,1.005400)); + hpcpush(hpxyz(0.092268,-0.021569,1.004479)); + hpcpush(hpxyz(0.081360,-0.028715,1.003715)); + hpcpush(hpxyz(0.077732,-0.029897,1.003462)); + hpcpush(hpxyz(0.069275,-0.029860,1.002841)); + hpcpush(hpxyz(0.059646,-0.029823,1.002221)); + hpcpush(hpxyz(0.051260,-0.033378,1.001869)); + hpcpush(hpxyz(0.046494,-0.040534,1.001901)); + hpcpush(hpxyz(0.045353,-0.053708,1.002468)); + hpcpush(hpxyz(0.049028,-0.066966,1.003438)); + hpcpush(hpxyz(0.053964,-0.082746,1.004868)); + hpcpush(hpxyz(0.065011,-0.097516,1.006845)); + hpcpush(hpxyz(0.079806,-0.108826,1.009065)); + hpcpush(hpxyz(0.094688,-0.115325,1.011072)); + hpcpush(hpxyz(0.118341,-0.115901,1.013626)); + hpcpush(hpxyz(0.098603,-0.124167,1.012492)); + hpcpush(hpxyz(0.112604,-0.134635,1.015286)); + hpcpush(hpxyz(0.097579,-0.132951,1.013508)); + hpcpush(hpxyz(0.104129,-0.144556,1.015746)); + hpcpush(hpxyz(0.086481,-0.135203,1.012798)); + hpcpush(hpxyz(0.067885,-0.127285,1.010351)); + hpcpush(hpxyz(0.040964,-0.113252,1.007226)); + hpcpush(hpxyz(0.025203,-0.099613,1.005265)); + hpcpush(hpxyz(0.000000,-0.078872,1.003106)); + hpcpush(hpxyz(-0.021516,-0.077698,1.003245)); + hpcpush(hpxyz(-0.044295,-0.077815,1.004001)); + hpcpush(hpxyz(-0.061108,-0.071892,1.004441)); + hpcpush(hpxyz(-0.084057,-0.063643,1.005543)); + hpcpush(hpxyz(-0.106144,-0.066340,1.007803)); + hpcpush(hpxyz(-0.116083,-0.068924,1.009072)); + hpcpush(hpxyz(-0.135091,-0.081542,1.012373)); + hpcpush(hpxyz(-0.162032,-0.087154,1.016784)); + hpcpush(hpxyz(-0.180298,-0.087679,1.019899)); + hpcpush(hpxyz(-0.194727,-0.083100,1.022166)); + hpcpush(hpxyz(-0.210870,-0.082352,1.025304)); + hpcpush(hpxyz(-0.230366,-0.088118,1.029968)); + hpcpush(hpxyz(-0.246310,-0.097762,1.034517)); + hpcpush(hpxyz(-0.237118,-0.081982,1.030993)); + hpcpush(hpxyz(-0.249897,-0.082453,1.034044)); + hpcpush(hpxyz(-0.241104,-0.075740,1.031440)); + hpcpush(hpxyz(-0.253563,-0.065926,1.033751)); + hpcpush(hpxyz(-0.242122,-0.064314,1.030902)); + hpcpush(hpxyz(-0.250414,-0.056912,1.032447)); + hpcpush(hpxyz(-0.173168,-0.066320,1.017047)); + hpcpush(hpxyz(-0.149626,-0.045009,1.012133)); + hpcpush(hpxyz(-0.158251,-0.009739,1.012491)); + hpcpush(hpxyz(-0.310601,-0.000000,1.047126)); + hpcpush(hpxyz(-0.310601,0.000000,1.047126)); + + bshape(shEagle, 33); + hpcpush(hpxyz(-0.153132,0.000000,1.011657)); + hpcpush(hpxyz(-0.151960,0.025529,1.011802)); + hpcpush(hpxyz(-0.192201,0.028337,1.018697)); + hpcpush(hpxyz(-0.204119,0.019793,1.020812)); + hpcpush(hpxyz(-0.201539,0.029674,1.020538)); + hpcpush(hpxyz(-0.208386,0.038452,1.022205)); + hpcpush(hpxyz(-0.200321,0.038333,1.020587)); + hpcpush(hpxyz(-0.199208,0.050730,1.020910)); + hpcpush(hpxyz(-0.192349,0.039456,1.019095)); + hpcpush(hpxyz(-0.149495,0.034031,1.011685)); + hpcpush(hpxyz(-0.148542,0.057225,1.012590)); + hpcpush(hpxyz(-0.089847,0.025157,1.004343)); + hpcpush(hpxyz(-0.048881,0.038151,1.001921)); + hpcpush(hpxyz(0.002416,0.130440,1.008474)); + hpcpush(hpxyz(-0.028450,0.202864,1.020766)); + hpcpush(hpxyz(-0.044701,0.209848,1.022758)); + hpcpush(hpxyz(-0.044823,0.216644,1.024180)); + hpcpush(hpxyz(-0.039848,0.217916,1.024244)); + hpcpush(hpxyz(-0.028602,0.216381,1.023542)); + hpcpush(hpxyz(-0.018604,0.210847,1.022156)); + hpcpush(hpxyz(-0.016122,0.210828,1.022110)); + hpcpush(hpxyz(-0.014922,0.217612,1.023512)); + hpcpush(hpxyz(-0.025023,0.231467,1.026744)); + hpcpush(hpxyz(-0.035205,0.241403,1.029327)); + hpcpush(hpxyz(-0.041644,0.248604,1.031280)); + hpcpush(hpxyz(-0.041754,0.254318,1.032677)); + hpcpush(hpxyz(-0.034211,0.258480,1.033432)); + hpcpush(hpxyz(-0.021481,0.253982,1.031973)); + hpcpush(hpxyz(-0.011317,0.243946,1.029387)); + hpcpush(hpxyz(0.001251,0.232708,1.026720)); + hpcpush(hpxyz(0.008728,0.224428,1.024912)); + hpcpush(hpxyz(0.009969,0.223059,1.024624)); + hpcpush(hpxyz(0.011289,0.238321,1.028068)); + hpcpush(hpxyz(0.003802,0.261058,1.033521)); + hpcpush(hpxyz(-0.005116,0.280126,1.038507)); + hpcpush(hpxyz(-0.007740,0.296717,1.043121)); + hpcpush(hpxyz(0.001286,0.290619,1.041375)); + hpcpush(hpxyz(0.012793,0.280166,1.038584)); + hpcpush(hpxyz(0.022854,0.264095,1.034538)); + hpcpush(hpxyz(0.028906,0.241303,1.029108)); + hpcpush(hpxyz(0.031328,0.234335,1.027567)); + hpcpush(hpxyz(0.032584,0.234354,1.027611)); + hpcpush(hpxyz(0.034119,0.252735,1.032007)); + hpcpush(hpxyz(0.032108,0.286405,1.040701)); + hpcpush(hpxyz(0.030917,0.292424,1.042338)); + hpcpush(hpxyz(0.039807,0.285067,1.040600)); + hpcpush(hpxyz(0.050896,0.264659,1.035681)); + hpcpush(hpxyz(0.058073,0.246178,1.031492)); + hpcpush(hpxyz(0.063739,0.221211,1.026156)); + hpcpush(hpxyz(0.083520,0.165812,1.017089)); + hpcpush(hpxyz(0.083035,0.146532,1.014084)); + hpcpush(hpxyz(0.075285,0.129928,1.011212)); + hpcpush(hpxyz(0.066581,0.122266,1.009645)); + hpcpush(hpxyz(0.055484,0.112174,1.007800)); + hpcpush(hpxyz(0.044365,0.087531,1.004803)); + hpcpush(hpxyz(0.034631,0.065680,1.002753)); + hpcpush(hpxyz(0.034631,0.065680,1.002753)); + hpcpush(hpxyz(0.026221,0.053634,1.001781)); + hpcpush(hpxyz(0.022616,0.041661,1.001123)); + hpcpush(hpxyz(0.021411,0.033306,1.000784)); + hpcpush(hpxyz(0.022591,0.024969,1.000567)); + hpcpush(hpxyz(0.026158,0.021402,1.000571)); + hpcpush(hpxyz(0.028538,0.020215,1.000611)); + hpcpush(hpxyz(0.034494,0.017842,1.000754)); + hpcpush(hpxyz(0.040463,0.020231,1.001023)); + hpcpush(hpxyz(0.042853,0.021427,1.001147)); + hpcpush(hpxyz(0.044051,0.022621,1.001225)); + hpcpush(hpxyz(0.051232,0.023829,1.001595)); + hpcpush(hpxyz(0.058426,0.023847,1.001989)); + hpcpush(hpxyz(0.064425,0.020282,1.002278)); + hpcpush(hpxyz(0.068025,0.015514,1.002431)); + hpcpush(hpxyz(0.071634,0.011939,1.002634)); + hpcpush(hpxyz(0.089791,0.002394,1.004026)); + hpcpush(hpxyz(0.089791,-0.002394,1.004026)); + hpcpush(hpxyz(0.071634,-0.011939,1.002634)); + hpcpush(hpxyz(0.068025,-0.015514,1.002431)); + hpcpush(hpxyz(0.064425,-0.020282,1.002278)); + hpcpush(hpxyz(0.058426,-0.023847,1.001989)); + hpcpush(hpxyz(0.051232,-0.023829,1.001595)); + hpcpush(hpxyz(0.044051,-0.022621,1.001225)); + hpcpush(hpxyz(0.042853,-0.021427,1.001147)); + hpcpush(hpxyz(0.040463,-0.020231,1.001023)); + hpcpush(hpxyz(0.034494,-0.017842,1.000754)); + hpcpush(hpxyz(0.028538,-0.020215,1.000611)); + hpcpush(hpxyz(0.026158,-0.021402,1.000571)); + hpcpush(hpxyz(0.022591,-0.024969,1.000567)); + hpcpush(hpxyz(0.021411,-0.033306,1.000784)); + hpcpush(hpxyz(0.022616,-0.041661,1.001123)); + hpcpush(hpxyz(0.026221,-0.053634,1.001781)); + hpcpush(hpxyz(0.034631,-0.065680,1.002753)); + hpcpush(hpxyz(0.034631,-0.065680,1.002753)); + hpcpush(hpxyz(0.044365,-0.087531,1.004803)); + hpcpush(hpxyz(0.055484,-0.112174,1.007800)); + hpcpush(hpxyz(0.066581,-0.122266,1.009645)); + hpcpush(hpxyz(0.075285,-0.129928,1.011212)); + hpcpush(hpxyz(0.083035,-0.146532,1.014084)); + hpcpush(hpxyz(0.083520,-0.165812,1.017089)); + hpcpush(hpxyz(0.063739,-0.221211,1.026156)); + hpcpush(hpxyz(0.058073,-0.246178,1.031492)); + hpcpush(hpxyz(0.050896,-0.264659,1.035681)); + hpcpush(hpxyz(0.039807,-0.285067,1.040600)); + hpcpush(hpxyz(0.030917,-0.292424,1.042338)); + hpcpush(hpxyz(0.032108,-0.286405,1.040701)); + hpcpush(hpxyz(0.034119,-0.252735,1.032007)); + hpcpush(hpxyz(0.032584,-0.234354,1.027611)); + hpcpush(hpxyz(0.031328,-0.234335,1.027567)); + hpcpush(hpxyz(0.028906,-0.241303,1.029108)); + hpcpush(hpxyz(0.022854,-0.264095,1.034538)); + hpcpush(hpxyz(0.012793,-0.280166,1.038584)); + hpcpush(hpxyz(0.001286,-0.290619,1.041375)); + hpcpush(hpxyz(-0.007740,-0.296717,1.043121)); + hpcpush(hpxyz(-0.005116,-0.280126,1.038507)); + hpcpush(hpxyz(0.003802,-0.261058,1.033521)); + hpcpush(hpxyz(0.011289,-0.238321,1.028068)); + hpcpush(hpxyz(0.009969,-0.223059,1.024624)); + hpcpush(hpxyz(0.008728,-0.224428,1.024912)); + hpcpush(hpxyz(0.001251,-0.232708,1.026720)); + hpcpush(hpxyz(-0.011317,-0.243946,1.029387)); + hpcpush(hpxyz(-0.021481,-0.253982,1.031973)); + hpcpush(hpxyz(-0.034211,-0.258480,1.033432)); + hpcpush(hpxyz(-0.041754,-0.254318,1.032677)); + hpcpush(hpxyz(-0.041644,-0.248604,1.031280)); + hpcpush(hpxyz(-0.035205,-0.241403,1.029327)); + hpcpush(hpxyz(-0.025023,-0.231467,1.026744)); + hpcpush(hpxyz(-0.014922,-0.217612,1.023512)); + hpcpush(hpxyz(-0.016122,-0.210828,1.022110)); + hpcpush(hpxyz(-0.018604,-0.210847,1.022156)); + hpcpush(hpxyz(-0.028602,-0.216381,1.023542)); + hpcpush(hpxyz(-0.039848,-0.217916,1.024244)); + hpcpush(hpxyz(-0.044823,-0.216644,1.024180)); + hpcpush(hpxyz(-0.044701,-0.209848,1.022758)); + hpcpush(hpxyz(-0.028450,-0.202864,1.020766)); + hpcpush(hpxyz(0.002416,-0.130440,1.008474)); + hpcpush(hpxyz(-0.048881,-0.038151,1.001921)); + hpcpush(hpxyz(-0.089847,-0.025157,1.004343)); + hpcpush(hpxyz(-0.148542,-0.057225,1.012590)); + hpcpush(hpxyz(-0.149495,-0.034031,1.011685)); + hpcpush(hpxyz(-0.192349,-0.039456,1.019095)); + hpcpush(hpxyz(-0.199208,-0.050730,1.020910)); + hpcpush(hpxyz(-0.200321,-0.038333,1.020587)); + hpcpush(hpxyz(-0.208386,-0.038452,1.022205)); + hpcpush(hpxyz(-0.201539,-0.029674,1.020538)); + hpcpush(hpxyz(-0.204119,-0.019793,1.020812)); + hpcpush(hpxyz(-0.192201,-0.028337,1.018697)); + hpcpush(hpxyz(-0.151960,-0.025529,1.011802)); + hpcpush(hpxyz(-0.153132,-0.000000,1.011657)); + hpcpush(hpxyz(-0.153132,0.000000,1.011657)); + + bshape(shSlime, 33); + for(int i=0; i<=84; i++) + hpcpush(ddi(i, crossf * (0.7 + .2 * sin(i * M_PI * 2 / 84 * 9))) * C0); + + bshape(shTentHead, 33); + hpcpush(hpxyz(-0.153133,-0.001215,1.011658)); + hpcpush(hpxyz(-0.153144,0.008508,1.011694)); + hpcpush(hpxyz(-0.148132,0.023070,1.011175)); + hpcpush(hpxyz(-0.142123,0.052233,1.011399)); + hpcpush(hpxyz(-0.146204,0.068228,1.012932)); + hpcpush(hpxyz(-0.177590,0.085095,1.019205)); + hpcpush(hpxyz(-0.224851,0.089187,1.028840)); + hpcpush(hpxyz(-0.262047,0.120747,1.040792)); + hpcpush(hpxyz(-0.255264,0.167153,1.045514)); + hpcpush(hpxyz(-0.229967,0.174723,1.040871)); + hpcpush(hpxyz(-0.184192,0.147855,1.027515)); + hpcpush(hpxyz(-0.138732,0.121544,1.016867)); + hpcpush(hpxyz(-0.108401,0.118145,1.012773)); + hpcpush(hpxyz(-0.102300,0.123003,1.012717)); + hpcpush(hpxyz(-0.091928,0.154439,1.016023)); + hpcpush(hpxyz(-0.090798,0.199010,1.023645)); + hpcpush(hpxyz(-0.056384,0.229293,1.027499)); + hpcpush(hpxyz(-0.011331,0.246774,1.030061)); + hpcpush(hpxyz(0.024027,0.255446,1.032390)); + hpcpush(hpxyz(0.073005,0.235380,1.029919)); + hpcpush(hpxyz(0.151935,0.187094,1.028634)); + hpcpush(hpxyz(0.146867,0.164292,1.023993)); + hpcpush(hpxyz(0.094648,0.162253,1.017489)); + hpcpush(hpxyz(0.044142,0.175341,1.016215)); + hpcpush(hpxyz(-0.003641,0.148054,1.010907)); + hpcpush(hpxyz(-0.002399,0.100774,1.005068)); + hpcpush(hpxyz(0.047859,0.071788,1.003715)); + hpcpush(hpxyz(0.098991,0.082090,1.008235)); + hpcpush(hpxyz(0.151038,0.106832,1.016969)); + hpcpush(hpxyz(0.199477,0.131730,1.028175)); + hpcpush(hpxyz(0.255339,0.129594,1.040189)); + hpcpush(hpxyz(0.264313,0.081720,1.037564)); + hpcpush(hpxyz(0.226731,0.063886,1.027370)); + hpcpush(hpxyz(0.168813,0.041592,1.015001)); + hpcpush(hpxyz(0.128034,0.026573,1.008513)); + hpcpush(hpxyz(0.108135,0.002403,1.005832)); + hpcpush(hpxyz(0.108135,-0.002403,1.005832)); + hpcpush(hpxyz(0.128034,-0.026573,1.008513)); + hpcpush(hpxyz(0.168813,-0.041592,1.015001)); + hpcpush(hpxyz(0.226731,-0.063886,1.027370)); + hpcpush(hpxyz(0.264313,-0.081720,1.037564)); + hpcpush(hpxyz(0.255339,-0.129594,1.040189)); + hpcpush(hpxyz(0.199477,-0.131730,1.028175)); + hpcpush(hpxyz(0.151038,-0.106832,1.016969)); + hpcpush(hpxyz(0.098991,-0.082090,1.008235)); + hpcpush(hpxyz(0.047859,-0.071788,1.003715)); + hpcpush(hpxyz(-0.002399,-0.100774,1.005068)); + hpcpush(hpxyz(-0.003641,-0.148054,1.010907)); + hpcpush(hpxyz(0.044142,-0.175341,1.016215)); + hpcpush(hpxyz(0.094648,-0.162253,1.017489)); + hpcpush(hpxyz(0.146867,-0.164292,1.023993)); + hpcpush(hpxyz(0.151935,-0.187094,1.028634)); + hpcpush(hpxyz(0.073005,-0.235380,1.029919)); + hpcpush(hpxyz(0.024027,-0.255446,1.032390)); + hpcpush(hpxyz(-0.011331,-0.246774,1.030061)); + hpcpush(hpxyz(-0.056384,-0.229293,1.027499)); + hpcpush(hpxyz(-0.090798,-0.199010,1.023645)); + hpcpush(hpxyz(-0.091928,-0.154439,1.016023)); + hpcpush(hpxyz(-0.102300,-0.123003,1.012717)); + hpcpush(hpxyz(-0.108401,-0.118145,1.012773)); + hpcpush(hpxyz(-0.138732,-0.121544,1.016867)); + hpcpush(hpxyz(-0.184192,-0.147855,1.027515)); + hpcpush(hpxyz(-0.229967,-0.174723,1.040871)); + hpcpush(hpxyz(-0.255264,-0.167153,1.045514)); + hpcpush(hpxyz(-0.262047,-0.120747,1.040792)); + hpcpush(hpxyz(-0.224851,-0.089187,1.028840)); + hpcpush(hpxyz(-0.177590,-0.085095,1.019205)); + hpcpush(hpxyz(-0.146204,-0.068228,1.012932)); + hpcpush(hpxyz(-0.142123,-0.052233,1.011399)); + hpcpush(hpxyz(-0.148132,-0.023070,1.011175)); + hpcpush(hpxyz(-0.153144,-0.008508,1.011694)); + hpcpush(hpxyz(-0.153133,0.001215,1.011658)); + hpcpush(hpxyz(-0.153133,-0.001215,1.011658)); + + bshape(shWormHead, 33); + hpcpush(hpxyz(-0.212131,-0.004962,1.022264)); + hpcpush(hpxyz(-0.213579,0.021110,1.022771)); + hpcpush(hpxyz(-0.208766,0.057162,1.023157)); + hpcpush(hpxyz(-0.193784,0.094408,1.022969)); + hpcpush(hpxyz(-0.171245,0.126572,1.022421)); + hpcpush(hpxyz(-0.149103,0.156559,1.023104)); + hpcpush(hpxyz(-0.121949,0.182923,1.023881)); + hpcpush(hpxyz(-0.099674,0.199349,1.024536)); + hpcpush(hpxyz(-0.073594,0.213299,1.025140)); + hpcpush(hpxyz(-0.039892,0.220654,1.024831)); + hpcpush(hpxyz(0.000000,0.225787,1.025173)); + hpcpush(hpxyz(0.051224,0.223636,1.025981)); + hpcpush(hpxyz(0.099986,0.207472,1.026178)); + hpcpush(hpxyz(0.126101,0.189776,1.025630)); + hpcpush(hpxyz(0.144643,0.172075,1.024954)); + hpcpush(hpxyz(0.260938,0.181352,1.049275)); + hpcpush(hpxyz(0.170506,0.139392,1.023964)); + hpcpush(hpxyz(0.241779,0.141997,1.038567)); + hpcpush(hpxyz(0.188983,0.108168,1.023433)); + hpcpush(hpxyz(0.239385,0.101327,1.033234)); + hpcpush(hpxyz(0.202657,0.079571,1.023426)); + hpcpush(hpxyz(0.238058,0.069276,1.030277)); + hpcpush(hpxyz(0.208736,0.055911,1.023082)); + hpcpush(hpxyz(0.237283,0.040175,1.028551)); + hpcpush(hpxyz(0.212303,0.028555,1.022687)); + hpcpush(hpxyz(0.235548,0.015035,1.027477)); + hpcpush(hpxyz(0.216200,0.001243,1.023105)); + hpcpush(hpxyz(0.216200,-0.001243,1.023105)); + hpcpush(hpxyz(0.235548,-0.015035,1.027477)); + hpcpush(hpxyz(0.212303,-0.028555,1.022687)); + hpcpush(hpxyz(0.237283,-0.040175,1.028551)); + hpcpush(hpxyz(0.208736,-0.055911,1.023082)); + hpcpush(hpxyz(0.238058,-0.069276,1.030277)); + hpcpush(hpxyz(0.202657,-0.079571,1.023426)); + hpcpush(hpxyz(0.239385,-0.101327,1.033234)); + hpcpush(hpxyz(0.188983,-0.108168,1.023433)); + hpcpush(hpxyz(0.241779,-0.141997,1.038567)); + hpcpush(hpxyz(0.170506,-0.139392,1.023964)); + hpcpush(hpxyz(0.260938,-0.181352,1.049275)); + hpcpush(hpxyz(0.144643,-0.172075,1.024954)); + hpcpush(hpxyz(0.126101,-0.189776,1.025630)); + hpcpush(hpxyz(0.099986,-0.207472,1.026178)); + hpcpush(hpxyz(0.051224,-0.223636,1.025981)); + hpcpush(hpxyz(0.000000,-0.225787,1.025173)); + hpcpush(hpxyz(-0.039892,-0.220654,1.024831)); + hpcpush(hpxyz(-0.073594,-0.213299,1.025140)); + hpcpush(hpxyz(-0.099674,-0.199349,1.024536)); + hpcpush(hpxyz(-0.121949,-0.182923,1.023881)); + hpcpush(hpxyz(-0.149103,-0.156559,1.023104)); + hpcpush(hpxyz(-0.171245,-0.126572,1.022421)); + hpcpush(hpxyz(-0.193784,-0.094408,1.022969)); + hpcpush(hpxyz(-0.208766,-0.057162,1.023157)); + hpcpush(hpxyz(-0.213579,-0.021110,1.022771)); + hpcpush(hpxyz(-0.212131,0.004962,1.022264)); + hpcpush(hpxyz(-0.212131,-0.004962,1.022264)); + + // bodyparts + + bshape(shPBody, 41); + hpcpush(hpxyz(-0.127943,0.000000,1.008151)); + hpcpush(hpxyz(-0.121732,0.008437,1.007417)); + hpcpush(hpxyz(-0.120752,0.047093,1.008364)); + hpcpush(hpxyz(-0.114785,0.065246,1.008679)); + hpcpush(hpxyz(-0.096531,0.082051,1.007993)); + hpcpush(hpxyz(-0.079664,0.100183,1.008158)); + hpcpush(hpxyz(-0.087015,0.156872,1.015963)); + hpcpush(hpxyz(-0.090442,0.188317,1.021588)); + hpcpush(hpxyz(-0.085023,0.215058,1.026391)); + hpcpush(hpxyz(-0.078296,0.241201,1.031653)); + hpcpush(hpxyz(-0.070101,0.263835,1.036592)); + hpcpush(hpxyz(-0.062700,0.273833,1.038709)); + hpcpush(hpxyz(-0.053763,0.276497,1.038913)); + hpcpush(hpxyz(-0.030638,0.274461,1.037433)); + hpcpush(hpxyz(-0.015319,0.275737,1.037432)); + hpcpush(hpxyz(0.001277,0.277150,1.037696)); + hpcpush(hpxyz(0.020384,0.271369,1.036367)); + hpcpush(hpxyz(0.038101,0.262896,1.034681)); + hpcpush(hpxyz(0.045596,0.255842,1.033215)); + hpcpush(hpxyz(0.062388,0.263558,1.036029)); + hpcpush(hpxyz(0.085371,0.258660,1.036433)); + hpcpush(hpxyz(0.084235,0.228817,1.029297)); + hpcpush(hpxyz(0.071073,0.213220,1.024946)); + hpcpush(hpxyz(0.048603,0.218088,1.024658)); + hpcpush(hpxyz(0.042541,0.228972,1.026761)); + hpcpush(hpxyz(0.028749,0.228742,1.026231)); + hpcpush(hpxyz(0.011222,0.224439,1.024938)); + hpcpush(hpxyz(-0.012498,0.229969,1.026178)); + hpcpush(hpxyz(-0.026261,0.230095,1.026466)); + hpcpush(hpxyz(-0.024880,0.217700,1.023725)); + hpcpush(hpxyz(-0.022225,0.198787,1.019809)); + hpcpush(hpxyz(-0.020850,0.180288,1.016336)); + hpcpush(hpxyz(-0.021870,0.150662,1.011522)); + hpcpush(hpxyz(-0.022997,0.136774,1.009572)); + hpcpush(hpxyz(-0.004819,0.120485,1.007244)); + hpcpush(hpxyz(0.007204,0.104455,1.005466)); + hpcpush(hpxyz(0.016748,0.083741,1.003640)); + hpcpush(hpxyz(0.026225,0.054833,1.001846)); + hpcpush(hpxyz(0.033323,0.030943,1.001033)); + hpcpush(hpxyz(0.034483,0.001189,1.000595)); + hpcpush(hpxyz(0.034483,-0.001189,1.000595)); + hpcpush(hpxyz(0.034483,0.001189,1.000595)); + hpcpush(hpxyz(0.034483,-0.001189,1.000595)); + hpcpush(hpxyz(0.033323,-0.030943,1.001033)); + hpcpush(hpxyz(0.026225,-0.054833,1.001846)); + hpcpush(hpxyz(0.016748,-0.083741,1.003640)); + hpcpush(hpxyz(0.007204,-0.104455,1.005466)); + hpcpush(hpxyz(-0.004819,-0.120485,1.007244)); + hpcpush(hpxyz(-0.022997,-0.136774,1.009572)); + hpcpush(hpxyz(-0.021870,-0.150662,1.011522)); + hpcpush(hpxyz(-0.020850,-0.180288,1.016336)); + hpcpush(hpxyz(-0.022225,-0.198787,1.019809)); + hpcpush(hpxyz(-0.024880,-0.217700,1.023725)); + hpcpush(hpxyz(-0.026261,-0.230095,1.026466)); + hpcpush(hpxyz(-0.012498,-0.229969,1.026178)); + hpcpush(hpxyz(0.011222,-0.224439,1.024938)); + hpcpush(hpxyz(0.028749,-0.228742,1.026231)); + hpcpush(hpxyz(0.042541,-0.228972,1.026761)); + hpcpush(hpxyz(0.048603,-0.218088,1.024658)); + hpcpush(hpxyz(0.071073,-0.213220,1.024946)); + hpcpush(hpxyz(0.084235,-0.228817,1.029297)); + hpcpush(hpxyz(0.085371,-0.258660,1.036433)); + hpcpush(hpxyz(0.062388,-0.263558,1.036029)); + hpcpush(hpxyz(0.045596,-0.255842,1.033215)); + hpcpush(hpxyz(0.038101,-0.262896,1.034681)); + hpcpush(hpxyz(0.020384,-0.271369,1.036367)); + hpcpush(hpxyz(0.001277,-0.277150,1.037696)); + hpcpush(hpxyz(-0.015319,-0.275737,1.037432)); + hpcpush(hpxyz(-0.030638,-0.274461,1.037433)); + hpcpush(hpxyz(-0.053763,-0.276497,1.038913)); + hpcpush(hpxyz(-0.062700,-0.273833,1.038709)); + hpcpush(hpxyz(-0.070101,-0.263835,1.036592)); + hpcpush(hpxyz(-0.078296,-0.241201,1.031653)); + hpcpush(hpxyz(-0.085023,-0.215058,1.026391)); + hpcpush(hpxyz(-0.090442,-0.188317,1.021588)); + hpcpush(hpxyz(-0.087015,-0.156872,1.015963)); + hpcpush(hpxyz(-0.079664,-0.100183,1.008158)); + hpcpush(hpxyz(-0.096531,-0.082051,1.007993)); + hpcpush(hpxyz(-0.114785,-0.065246,1.008679)); + hpcpush(hpxyz(-0.120752,-0.047093,1.008364)); + hpcpush(hpxyz(-0.121732,-0.008437,1.007417)); + hpcpush(hpxyz(-0.127943,-0.000000,1.008151)); + hpcpush(hpxyz(-0.127943,0.000000,1.008151)); + + bshape(shYeti, 41); + hpcpush(hpxyz(-0.146785,0.001213,1.010716)); + hpcpush(hpxyz(-0.119261,0.012047,1.007158)); + hpcpush(hpxyz(-0.134264,0.022982,1.009235)); + hpcpush(hpxyz(-0.116850,0.026502,1.007153)); + hpcpush(hpxyz(-0.128124,0.037470,1.008871)); + hpcpush(hpxyz(-0.114489,0.040975,1.007366)); + hpcpush(hpxyz(-0.134526,0.049690,1.010231)); + hpcpush(hpxyz(-0.108483,0.056652,1.007461)); + hpcpush(hpxyz(-0.124869,0.072739,1.010388)); + hpcpush(hpxyz(-0.100038,0.069906,1.007420)); + hpcpush(hpxyz(-0.116319,0.082393,1.010108)); + hpcpush(hpxyz(-0.086776,0.085571,1.007399)); + hpcpush(hpxyz(-0.105410,0.095717,1.010086)); + hpcpush(hpxyz(-0.078461,0.101396,1.008185)); + hpcpush(hpxyz(-0.084756,0.111394,1.009749)); + hpcpush(hpxyz(-0.078850,0.123734,1.010706)); + hpcpush(hpxyz(-0.094972,0.127846,1.012603)); + hpcpush(hpxyz(-0.081624,0.138883,1.012892)); + hpcpush(hpxyz(-0.102733,0.139423,1.014886)); + hpcpush(hpxyz(-0.083221,0.154204,1.015236)); + hpcpush(hpxyz(-0.115566,0.148760,1.017588)); + hpcpush(hpxyz(-0.081064,0.167041,1.017091)); + hpcpush(hpxyz(-0.093630,0.170012,1.018661)); + hpcpush(hpxyz(-0.081530,0.184060,1.020061)); + hpcpush(hpxyz(-0.104404,0.190164,1.023261)); + hpcpush(hpxyz(-0.078114,0.195904,1.021998)); + hpcpush(hpxyz(-0.088688,0.211101,1.025880)); + hpcpush(hpxyz(-0.074815,0.211977,1.024954)); + hpcpush(hpxyz(-0.081589,0.225940,1.028448)); + hpcpush(hpxyz(-0.067678,0.226847,1.027638)); + hpcpush(hpxyz(-0.091419,0.248863,1.034548)); + hpcpush(hpxyz(-0.059306,0.244796,1.031234)); + hpcpush(hpxyz(-0.060896,0.256271,1.034110)); + hpcpush(hpxyz(-0.051997,0.257446,1.033916)); + hpcpush(hpxyz(-0.058919,0.276663,1.039237)); + hpcpush(hpxyz(-0.042072,0.270280,1.036736)); + hpcpush(hpxyz(-0.042449,0.288141,1.041550)); + hpcpush(hpxyz(-0.020355,0.268437,1.035603)); + hpcpush(hpxyz(-0.007716,0.290637,1.041407)); + hpcpush(hpxyz(0.001272,0.268323,1.035374)); + hpcpush(hpxyz(0.017995,0.289206,1.041136)); + hpcpush(hpxyz(0.021598,0.265534,1.034879)); + hpcpush(hpxyz(0.038374,0.277573,1.038518)); + hpcpush(hpxyz(0.037997,0.257112,1.033223)); + hpcpush(hpxyz(0.048725,0.280810,1.039821)); + hpcpush(hpxyz(0.050653,0.254534,1.033128)); + hpcpush(hpxyz(0.069009,0.269645,1.038013)); + hpcpush(hpxyz(0.085977,0.273328,1.040241)); + hpcpush(hpxyz(0.075050,0.258222,1.035525)); + hpcpush(hpxyz(0.097049,0.259223,1.037601)); + hpcpush(hpxyz(0.103016,0.248003,1.035431)); + hpcpush(hpxyz(0.079575,0.241251,1.031763)); + hpcpush(hpxyz(0.091636,0.222186,1.028476)); + hpcpush(hpxyz(0.070376,0.232494,1.029080)); + hpcpush(hpxyz(0.072102,0.205119,1.023363)); + hpcpush(hpxyz(0.060388,0.237778,1.029653)); + hpcpush(hpxyz(0.058115,0.195365,1.020561)); + hpcpush(hpxyz(0.045217,0.237388,1.028784)); + hpcpush(hpxyz(0.037611,0.234439,1.027802)); + hpcpush(hpxyz(0.034796,0.213746,1.023180)); + hpcpush(hpxyz(0.023715,0.225917,1.025476)); + hpcpush(hpxyz(0.027226,0.204191,1.020997)); + hpcpush(hpxyz(0.012420,0.214873,1.022900)); + hpcpush(hpxyz(0.020917,0.189485,1.018009)); + hpcpush(hpxyz(0.003700,0.197357,1.019296)); + hpcpush(hpxyz(0.009817,0.182844,1.016626)); + hpcpush(hpxyz(-0.011065,0.188106,1.017598)); + hpcpush(hpxyz(0.003663,0.168520,1.014107)); + hpcpush(hpxyz(-0.023305,0.180308,1.016393)); + hpcpush(hpxyz(-0.004879,0.164654,1.013477)); + hpcpush(hpxyz(-0.034247,0.170012,1.014927)); + hpcpush(hpxyz(-0.004861,0.153136,1.011669)); + hpcpush(hpxyz(-0.027964,0.151980,1.011870)); + hpcpush(hpxyz(-0.003639,0.146787,1.010722)); + hpcpush(hpxyz(-0.015710,0.131722,1.008760)); + hpcpush(hpxyz(0.010889,0.136717,1.009361)); + hpcpush(hpxyz(-0.003615,0.120484,1.007239)); + hpcpush(hpxyz(0.027708,0.116858,1.007186)); + hpcpush(hpxyz(0.007202,0.103229,1.005340)); + hpcpush(hpxyz(0.034761,0.089899,1.004634)); + hpcpush(hpxyz(0.015548,0.082525,1.003520)); + hpcpush(hpxyz(0.044270,0.074183,1.003725)); + hpcpush(hpxyz(0.021490,0.069245,1.002625)); + hpcpush(hpxyz(0.051357,0.054940,1.002824)); + hpcpush(hpxyz(0.027405,0.050043,1.001626)); + hpcpush(hpxyz(0.053662,0.034582,1.002036)); + hpcpush(hpxyz(0.034521,0.033331,1.001151)); + hpcpush(hpxyz(0.060848,0.029827,1.002293)); + hpcpush(hpxyz(0.041653,0.017851,1.001026)); + hpcpush(hpxyz(0.065617,0.015510,1.002271)); + hpcpush(hpxyz(0.051204,0.004763,1.001321)); + hpcpush(hpxyz(0.051204,-0.004763,1.001321)); + hpcpush(hpxyz(0.065617,-0.015510,1.002271)); + hpcpush(hpxyz(0.041653,-0.017851,1.001026)); + hpcpush(hpxyz(0.060848,-0.029827,1.002293)); + hpcpush(hpxyz(0.034521,-0.033331,1.001151)); + hpcpush(hpxyz(0.053662,-0.034582,1.002036)); + hpcpush(hpxyz(0.027405,-0.050043,1.001626)); + hpcpush(hpxyz(0.051357,-0.054940,1.002824)); + hpcpush(hpxyz(0.021490,-0.069245,1.002625)); + hpcpush(hpxyz(0.044270,-0.074183,1.003725)); + hpcpush(hpxyz(0.015548,-0.082525,1.003520)); + hpcpush(hpxyz(0.034761,-0.089899,1.004634)); + hpcpush(hpxyz(0.007202,-0.103229,1.005340)); + hpcpush(hpxyz(0.027708,-0.116858,1.007186)); + hpcpush(hpxyz(-0.003615,-0.120484,1.007239)); + hpcpush(hpxyz(0.010889,-0.136717,1.009361)); + hpcpush(hpxyz(-0.015710,-0.131722,1.008760)); + hpcpush(hpxyz(-0.003639,-0.146787,1.010722)); + hpcpush(hpxyz(-0.027964,-0.151980,1.011870)); + hpcpush(hpxyz(-0.004861,-0.153136,1.011669)); + hpcpush(hpxyz(-0.034247,-0.170012,1.014927)); + hpcpush(hpxyz(-0.004879,-0.164654,1.013477)); + hpcpush(hpxyz(-0.023305,-0.180308,1.016393)); + hpcpush(hpxyz(0.003663,-0.168520,1.014107)); + hpcpush(hpxyz(-0.011065,-0.188106,1.017598)); + hpcpush(hpxyz(0.009817,-0.182844,1.016626)); + hpcpush(hpxyz(0.003700,-0.197357,1.019296)); + hpcpush(hpxyz(0.020917,-0.189485,1.018009)); + hpcpush(hpxyz(0.012420,-0.214873,1.022900)); + hpcpush(hpxyz(0.027226,-0.204191,1.020997)); + hpcpush(hpxyz(0.023715,-0.225917,1.025476)); + hpcpush(hpxyz(0.034796,-0.213746,1.023180)); + hpcpush(hpxyz(0.037611,-0.234439,1.027802)); + hpcpush(hpxyz(0.045217,-0.237388,1.028784)); + hpcpush(hpxyz(0.058115,-0.195365,1.020561)); + hpcpush(hpxyz(0.060388,-0.237778,1.029653)); + hpcpush(hpxyz(0.072102,-0.205119,1.023363)); + hpcpush(hpxyz(0.070376,-0.232494,1.029080)); + hpcpush(hpxyz(0.091636,-0.222186,1.028476)); + hpcpush(hpxyz(0.079575,-0.241251,1.031763)); + hpcpush(hpxyz(0.103016,-0.248003,1.035431)); + hpcpush(hpxyz(0.097049,-0.259223,1.037601)); + hpcpush(hpxyz(0.075050,-0.258222,1.035525)); + hpcpush(hpxyz(0.085977,-0.273328,1.040241)); + hpcpush(hpxyz(0.069009,-0.269645,1.038013)); + hpcpush(hpxyz(0.050653,-0.254534,1.033128)); + hpcpush(hpxyz(0.048725,-0.280810,1.039821)); + hpcpush(hpxyz(0.037997,-0.257112,1.033223)); + hpcpush(hpxyz(0.038374,-0.277573,1.038518)); + hpcpush(hpxyz(0.021598,-0.265534,1.034879)); + hpcpush(hpxyz(0.017995,-0.289206,1.041136)); + hpcpush(hpxyz(0.001272,-0.268323,1.035374)); + hpcpush(hpxyz(-0.007716,-0.290637,1.041407)); + hpcpush(hpxyz(-0.020355,-0.268437,1.035603)); + hpcpush(hpxyz(-0.042449,-0.288141,1.041550)); + hpcpush(hpxyz(-0.042072,-0.270280,1.036736)); + hpcpush(hpxyz(-0.058919,-0.276663,1.039237)); + hpcpush(hpxyz(-0.051997,-0.257446,1.033916)); + hpcpush(hpxyz(-0.060896,-0.256271,1.034110)); + hpcpush(hpxyz(-0.059306,-0.244796,1.031234)); + hpcpush(hpxyz(-0.091419,-0.248863,1.034548)); + hpcpush(hpxyz(-0.067678,-0.226847,1.027638)); + hpcpush(hpxyz(-0.081589,-0.225940,1.028448)); + hpcpush(hpxyz(-0.074815,-0.211977,1.024954)); + hpcpush(hpxyz(-0.088688,-0.211101,1.025880)); + hpcpush(hpxyz(-0.078114,-0.195904,1.021998)); + hpcpush(hpxyz(-0.104404,-0.190164,1.023261)); + hpcpush(hpxyz(-0.081530,-0.184060,1.020061)); + hpcpush(hpxyz(-0.093630,-0.170012,1.018661)); + hpcpush(hpxyz(-0.081064,-0.167041,1.017091)); + hpcpush(hpxyz(-0.115566,-0.148760,1.017588)); + hpcpush(hpxyz(-0.083221,-0.154204,1.015236)); + hpcpush(hpxyz(-0.102733,-0.139423,1.014886)); + hpcpush(hpxyz(-0.081624,-0.138883,1.012892)); + hpcpush(hpxyz(-0.094972,-0.127846,1.012603)); + hpcpush(hpxyz(-0.078850,-0.123734,1.010706)); + hpcpush(hpxyz(-0.084756,-0.111394,1.009749)); + hpcpush(hpxyz(-0.078461,-0.101396,1.008185)); + hpcpush(hpxyz(-0.105410,-0.095717,1.010086)); + hpcpush(hpxyz(-0.086776,-0.085571,1.007399)); + hpcpush(hpxyz(-0.116319,-0.082393,1.010108)); + hpcpush(hpxyz(-0.100038,-0.069906,1.007420)); + hpcpush(hpxyz(-0.124869,-0.072739,1.010388)); + hpcpush(hpxyz(-0.108483,-0.056652,1.007461)); + hpcpush(hpxyz(-0.134526,-0.049690,1.010231)); + hpcpush(hpxyz(-0.114489,-0.040975,1.007366)); + hpcpush(hpxyz(-0.128124,-0.037470,1.008871)); + hpcpush(hpxyz(-0.116850,-0.026502,1.007153)); + hpcpush(hpxyz(-0.134264,-0.022982,1.009235)); + hpcpush(hpxyz(-0.119261,-0.012047,1.007158)); + hpcpush(hpxyz(-0.146785,-0.001213,1.010716)); + hpcpush(hpxyz(-0.146785,0.001213,1.010716)); + + bshape(shPSword, 42); + hpcpush(hpxyz(0.093822,0.244697,1.033769)); + hpcpush(hpxyz(0.105758,0.251015,1.036433)); + hpcpush(hpxyz(0.110908,0.249862,1.036693)); + hpcpush(hpxyz(0.110690,0.245554,1.035640)); + hpcpush(hpxyz(0.113376,0.247134,1.036306)); + hpcpush(hpxyz(0.117228,0.245924,1.036446)); + hpcpush(hpxyz(0.127263,0.237981,1.035775)); + hpcpush(hpxyz(0.131886,0.226997,1.033887)); + hpcpush(hpxyz(0.116494,0.231721,1.033085)); + hpcpush(hpxyz(0.106117,0.231182,1.031846)); + hpcpush(hpxyz(0.105927,0.226986,1.030894)); + hpcpush(hpxyz(0.263283,-0.174653,1.048724)); + hpcpush(hpxyz(0.086104,0.209645,1.025361)); + hpcpush(hpxyz(0.079571,0.202657,1.023426)); + hpcpush(hpxyz(0.074206,0.190462,1.020677)); + hpcpush(hpxyz(0.068951,0.179766,1.018366)); + hpcpush(hpxyz(0.065727,0.200902,1.022097)); + hpcpush(hpxyz(0.068444,0.209067,1.023911)); + hpcpush(hpxyz(0.077641,0.221653,1.027209)); + hpcpush(hpxyz(0.086737,0.227526,1.029219)); + hpcpush(hpxyz(0.086260,0.248631,1.034049)); + hpcpush(hpxyz(0.086431,0.252937,1.035107)); + hpcpush(hpxyz(0.093822,0.244697,1.033769)); + + bshape(shHedgehogBlade, 42); + hpcpush(hpxyz(0.117178,0.032617,1.007370)); + hpcpush(hpxyz(0.102699,0.066452,1.007454)); + hpcpush(hpxyz(0.056807,0.109987,1.007633)); + hpcpush(hpxyz(0.052506,0.272774,1.037864)); + hpcpush(hpxyz(0.079931,0.279758,1.041467)); + hpcpush(hpxyz(0.082589,0.170109,1.017722)); +//hpcpush(hpxyz(0.173109,0.220554,1.038562)); + hpcpush(hpxyz(0.139258,0.126935,1.017598)); + hpcpush(hpxyz(0.240653,0.136967,1.037629)); + hpcpush(hpxyz(0.177567,0.067821,1.017905)); + hpcpush(hpxyz(0.273978,0.042249,1.037713)); + hpcpush(hpxyz(0.187242,-0.000000,1.017379)); + hpcpush(hpxyz(0.187242,0.000000,1.017379)); + hpcpush(hpxyz(0.273978,-0.042249,1.037713)); + hpcpush(hpxyz(0.177567,-0.067821,1.017905)); + hpcpush(hpxyz(0.240653,-0.136967,1.037629)); + hpcpush(hpxyz(0.139258,-0.126935,1.017598)); +//hpcpush(hpxyz(0.173109,-0.220554,1.038562)); + hpcpush(hpxyz(0.082589,-0.170109,1.017722)); + hpcpush(hpxyz(0.079931,-0.279758,1.041467)); + hpcpush(hpxyz(0.052506,-0.272774,1.037864)); + hpcpush(hpxyz(0.056807,-0.109987,1.007633)); + hpcpush(hpxyz(0.102699,-0.066452,1.007454)); + hpcpush(hpxyz(0.117178,-0.032617,1.007370)); + hpcpush(hpxyz(0.117178,0.032617,1.007370)); + + bshape(shHedgehogBladePlayer, 42); + hpcpush(hpxyz(0.117178,0.032617,1.007370)); + hpcpush(hpxyz(0.102699,0.066452,1.007454)); + hpcpush(hpxyz(0.056807,0.109987,1.007633)); + hpcpush(hpxyz(0.052506,0.272774,1.037864)); + hpcpush(hpxyz(0.079931,0.279758,1.041467)); + hpcpush(hpxyz(0.082589,0.170109,1.017722)); + hpcpush(hpxyz(0.173109,0.220554,1.038562)); + hpcpush(hpxyz(0.139258,0.126935,1.017598)); + hpcpush(hpxyz(0.240653,0.136967,1.037629)); + hpcpush(hpxyz(0.177567,0.067821,1.017905)); + hpcpush(hpxyz(0.273978,0.042249,1.037713)); + hpcpush(hpxyz(0.187242,-0.000000,1.017379)); + hpcpush(hpxyz(0.187242,0.000000,1.017379)); + hpcpush(hpxyz(0.273978,-0.042249,1.037713)); + hpcpush(hpxyz(0.177567,-0.067821,1.017905)); + hpcpush(hpxyz(0.240653,-0.136967,1.037629)); + hpcpush(hpxyz(0.139258,-0.126935,1.017598)); + hpcpush(hpxyz(0.173109,-0.220554,1.038562)); + hpcpush(hpxyz(0.082589,-0.170109,1.017722)); + hpcpush(hpxyz(0.079931,-0.279758,1.041467)); + hpcpush(hpxyz(0.052506,-0.272774,1.037864)); + hpcpush(hpxyz(0.056807,-0.109987,1.007633)); + hpcpush(hpxyz(0.102699,-0.066452,1.007454)); + hpcpush(hpxyz(0.117178,-0.032617,1.007370)); + hpcpush(hpxyz(0.117178,0.032617,1.007370)); + + bshape(shFemaleBody, 41); + hpcpush(hpxyz(-0.091723,0.073620,1.006893)); + hpcpush(hpxyz(-0.089581,0.094424,1.008435)); + hpcpush(hpxyz(-0.082621,0.117856,1.010305)); + hpcpush(hpxyz(-0.070099,0.258731,1.035304)); + hpcpush(hpxyz(-0.058825,0.268551,1.037102)); + hpcpush(hpxyz(-0.003834,0.273475,1.036727)); + hpcpush(hpxyz(0.040760,0.263668,1.034979)); + hpcpush(hpxyz(0.077891,0.260490,1.036302)); + hpcpush(hpxyz(0.085895,0.233685,1.030527)); + hpcpush(hpxyz(0.064882,0.210867,1.024048)); + hpcpush(hpxyz(0.037427,0.217075,1.023974)); + hpcpush(hpxyz(0.011258,0.226410,1.025372)); + hpcpush(hpxyz(-0.037448,0.218444,1.024266)); + hpcpush(hpxyz(-0.026537,0.112181,1.006622)); + hpcpush(hpxyz(-0.015609,0.091250,1.004276)); + hpcpush(hpxyz(0.007196,0.086357,1.003748)); + hpcpush(hpxyz(0.019189,0.083950,1.003701)); + hpcpush(hpxyz(0.027568,0.077909,1.003409)); + hpcpush(hpxyz(0.033526,0.068249,1.002887)); + hpcpush(hpxyz(0.034689,0.059808,1.002387)); + hpcpush(hpxyz(0.037035,0.046593,1.001770)); + hpcpush(hpxyz(0.029813,0.028620,1.000854)); + hpcpush(hpxyz(0.017865,0.010719,1.000217)); + hpcpush(hpxyz(0.010716,0.003572,1.000064)); + hpcpush(hpxyz(0.010716,-0.003572,1.000064)); + hpcpush(hpxyz(0.017865,-0.010719,1.000217)); + hpcpush(hpxyz(0.029813,-0.028620,1.000854)); + hpcpush(hpxyz(0.037035,-0.046593,1.001770)); + hpcpush(hpxyz(0.034689,-0.059808,1.002387)); + hpcpush(hpxyz(0.033526,-0.068249,1.002887)); + hpcpush(hpxyz(0.027568,-0.077909,1.003409)); + hpcpush(hpxyz(0.019189,-0.083950,1.003701)); + hpcpush(hpxyz(0.007196,-0.086357,1.003748)); + hpcpush(hpxyz(-0.015609,-0.091250,1.004276)); + hpcpush(hpxyz(-0.026537,-0.112181,1.006622)); + hpcpush(hpxyz(-0.037448,-0.218444,1.024266)); + hpcpush(hpxyz(0.011258,-0.226410,1.025372)); + hpcpush(hpxyz(0.037427,-0.217075,1.023974)); + hpcpush(hpxyz(0.064882,-0.210867,1.024048)); + hpcpush(hpxyz(0.085895,-0.233685,1.030527)); + hpcpush(hpxyz(0.077891,-0.260490,1.036302)); + hpcpush(hpxyz(0.040760,-0.263668,1.034979)); + hpcpush(hpxyz(-0.003834,-0.273475,1.036727)); + hpcpush(hpxyz(-0.058825,-0.268551,1.037102)); + hpcpush(hpxyz(-0.070099,-0.258731,1.035304)); + hpcpush(hpxyz(-0.082621,-0.117856,1.010305)); + hpcpush(hpxyz(-0.089581,-0.094424,1.008435)); + hpcpush(hpxyz(-0.091723,-0.073620,1.006893)); + hpcpush(hpxyz(-0.091723,0.073620,1.006893)); + + bshape(shFemaleDress, 42); + hpcpush(hpxyz(-0.094893,0.000000,1.004492)); + hpcpush(hpxyz(-0.098831,0.051826,1.006207)); + hpcpush(hpxyz(-0.095833,0.099473,1.009494)); + hpcpush(hpxyz(-0.087712,0.125476,1.011651)); + hpcpush(hpxyz(-0.020535,0.119586,1.007334)); + hpcpush(hpxyz(-0.012011,0.093684,1.004451)); + hpcpush(hpxyz(0.001200,0.088788,1.003935)); + hpcpush(hpxyz(0.021589,0.083958,1.003751)); + hpcpush(hpxyz(0.033549,0.073088,1.003228)); + hpcpush(hpxyz(0.041871,0.056227,1.002454)); + hpcpush(hpxyz(0.039397,0.035815,1.001416)); + hpcpush(hpxyz(0.030996,0.021459,1.000710)); + hpcpush(hpxyz(0.019057,0.011911,1.000252)); + hpcpush(hpxyz(0.010716,-0.001191,1.000058)); + hpcpush(hpxyz(0.010716,0.001191,1.000058)); + hpcpush(hpxyz(0.019057,-0.011911,1.000252)); + hpcpush(hpxyz(0.030996,-0.021459,1.000710)); + hpcpush(hpxyz(0.039397,-0.035815,1.001416)); + hpcpush(hpxyz(0.041871,-0.056227,1.002454)); + hpcpush(hpxyz(0.033549,-0.073088,1.003228)); + hpcpush(hpxyz(0.021589,-0.083958,1.003751)); + hpcpush(hpxyz(0.001200,-0.088788,1.003935)); + hpcpush(hpxyz(-0.012011,-0.093684,1.004451)); + hpcpush(hpxyz(-0.020535,-0.119586,1.007334)); + hpcpush(hpxyz(-0.087712,-0.125476,1.011651)); + hpcpush(hpxyz(-0.095833,-0.099473,1.009494)); + hpcpush(hpxyz(-0.098831,-0.051826,1.006207)); + hpcpush(hpxyz(-0.094893,-0.000000,1.004492)); + hpcpush(hpxyz(-0.094893,0.000000,1.004492)); + + bshape(shDemon, 43); + drawDemon(1); + + bshape(shKnightArmor, 42); + hpcpush(hpxyz(-0.129512,-0.004842,1.008363)); + hpcpush(hpxyz(-0.129934,0.057074,1.010020)); + hpcpush(hpxyz(-0.089756,0.104311,1.009424)); + hpcpush(hpxyz(-0.099124,0.177184,1.020402)); + hpcpush(hpxyz(-0.086054,0.237913,1.031508)); + hpcpush(hpxyz(-0.019952,0.218220,1.023727)); + hpcpush(hpxyz(-0.020812,0.167721,1.014181)); + hpcpush(hpxyz(-0.024311,0.143434,1.010527)); + hpcpush(hpxyz(0.006041,0.122026,1.007436)); + hpcpush(hpxyz(0.026372,0.079117,1.003471)); + hpcpush(hpxyz(0.032239,0.044179,1.001494)); + hpcpush(hpxyz(0.034575,0.016691,1.000737)); + hpcpush(hpxyz(0.034565,0.003576,1.000604)); + hpcpush(hpxyz(0.034565,-0.003576,1.000604)); + hpcpush(hpxyz(0.034575,-0.016691,1.000737)); + hpcpush(hpxyz(0.032239,-0.044179,1.001494)); + hpcpush(hpxyz(0.026372,-0.079117,1.003471)); + hpcpush(hpxyz(0.006041,-0.122026,1.007436)); + hpcpush(hpxyz(-0.024311,-0.143434,1.010527)); + hpcpush(hpxyz(-0.020812,-0.167721,1.014181)); + hpcpush(hpxyz(-0.019952,-0.218220,1.023727)); + hpcpush(hpxyz(-0.086054,-0.237913,1.031508)); + hpcpush(hpxyz(-0.099124,-0.177184,1.020402)); + hpcpush(hpxyz(-0.089756,-0.104311,1.009424)); + hpcpush(hpxyz(-0.129934,-0.057074,1.010020)); + hpcpush(hpxyz(-0.129512,0.004842,1.008363)); + hpcpush(hpxyz(-0.129512,-0.004842,1.008363)); + + bshape(shKnightCloak, 43); + hpcpush(hpxyz(-0.000015,0.003765,1.000007)); + hpcpush(hpxyz(0.007931,-0.006370,1.000052)); + hpcpush(hpxyz(0.020079,-0.026681,1.000557)); + hpcpush(hpxyz(0.029245,-0.044814,1.001431)); + hpcpush(hpxyz(0.027073,-0.059250,1.002120)); + hpcpush(hpxyz(0.023423,-0.078357,1.003339)); + hpcpush(hpxyz(0.002361,-0.116363,1.006750)); + hpcpush(hpxyz(-0.019415,-0.136638,1.009478)); + hpcpush(hpxyz(-0.058154,-0.153287,1.013350)); + hpcpush(hpxyz(-0.094935,-0.166174,1.018149)); + hpcpush(hpxyz(-0.136465,-0.178800,1.024984)); + hpcpush(hpxyz(-0.161844,-0.181507,1.029144)); + hpcpush(hpxyz(-0.184577,-0.179578,1.032626)); + hpcpush(hpxyz(-0.162984,-0.162667,1.026170)); + hpcpush(hpxyz(-0.150295,-0.135739,1.020301)); + hpcpush(hpxyz(-0.152621,-0.120097,1.018684)); + hpcpush(hpxyz(-0.161098,-0.102831,1.018100)); + hpcpush(hpxyz(-0.167882,-0.095516,1.018483)); + hpcpush(hpxyz(-0.184530,-0.081393,1.020135)); + hpcpush(hpxyz(-0.163316,-0.053335,1.014651)); + hpcpush(hpxyz(-0.149316,-0.029081,1.011504)); + hpcpush(hpxyz(-0.143262,-0.011700,1.010278)); + hpcpush(hpxyz(-0.140925,0.006746,1.009904)); + hpcpush(hpxyz(-0.140925,-0.006746,1.009904)); + hpcpush(hpxyz(-0.143262,0.011700,1.010278)); + hpcpush(hpxyz(-0.149316,0.029081,1.011504)); + hpcpush(hpxyz(-0.163316,0.053335,1.014651)); + hpcpush(hpxyz(-0.184530,0.081393,1.020135)); + hpcpush(hpxyz(-0.167882,0.095516,1.018483)); + hpcpush(hpxyz(-0.161098,0.102831,1.018100)); + hpcpush(hpxyz(-0.152621,0.120097,1.018684)); + hpcpush(hpxyz(-0.150295,0.135739,1.020301)); + hpcpush(hpxyz(-0.162984,0.162667,1.026170)); + hpcpush(hpxyz(-0.184577,0.179578,1.032626)); + hpcpush(hpxyz(-0.161844,0.181507,1.029144)); + hpcpush(hpxyz(-0.136465,0.178800,1.024984)); + hpcpush(hpxyz(-0.094935,0.166174,1.018149)); + hpcpush(hpxyz(-0.058154,0.153287,1.013350)); + hpcpush(hpxyz(-0.019415,0.136638,1.009478)); + hpcpush(hpxyz(0.002361,0.116363,1.006750)); + hpcpush(hpxyz(0.023423,0.078357,1.003339)); + hpcpush(hpxyz(0.027073,0.059250,1.002120)); + hpcpush(hpxyz(0.029245,0.044814,1.001431)); + hpcpush(hpxyz(0.020079,0.026681,1.000557)); + hpcpush(hpxyz(0.007931,0.006370,1.000052)); + hpcpush(hpxyz(-0.000015,-0.003765,1.000007)); + hpcpush(hpxyz(-0.000015,0.003765,1.000007)); + + bshape(shArmor, 42); + hpcpush(hpxyz(-0.131705,0.010875,1.008694)); + hpcpush(hpxyz(-0.133453,0.061874,1.010761)); + hpcpush(hpxyz(-0.093134,0.099182,1.009213)); + hpcpush(hpxyz(-0.097643,0.135480,1.013849)); + hpcpush(hpxyz(-0.010956,0.158255,1.012504)); + hpcpush(hpxyz(0.016844,0.113094,1.006516)); + hpcpush(hpxyz(0.022740,0.084974,1.003861)); + hpcpush(hpxyz(-0.062459,0.086481,1.005674)); + hpcpush(hpxyz(-0.061152,0.076740,1.004803)); + hpcpush(hpxyz(0.063569,0.076763,1.004954)); + hpcpush(hpxyz(0.074360,0.065964,1.004928)); + hpcpush(hpxyz(0.083920,0.049153,1.004718)); + hpcpush(hpxyz(0.088667,0.032352,1.004444)); + hpcpush(hpxyz(0.092226,0.002395,1.004247)); + hpcpush(hpxyz(0.057196,0.007150,1.001660)); + hpcpush(hpxyz(0.054891,0.041765,1.002376)); + hpcpush(hpxyz(0.039313,0.039313,1.001544)); + hpcpush(hpxyz(0.039313,-0.039313,1.001544)); + hpcpush(hpxyz(0.054891,-0.041765,1.002376)); + hpcpush(hpxyz(0.057196,-0.007150,1.001660)); + hpcpush(hpxyz(0.092226,-0.002395,1.004247)); + hpcpush(hpxyz(0.088667,-0.032352,1.004444)); + hpcpush(hpxyz(0.083920,-0.049153,1.004718)); + hpcpush(hpxyz(0.074360,-0.065964,1.004928)); + hpcpush(hpxyz(0.063569,-0.076763,1.004954)); + hpcpush(hpxyz(-0.061152,-0.076740,1.004803)); + hpcpush(hpxyz(-0.062459,-0.086481,1.005674)); + hpcpush(hpxyz(0.022740,-0.084974,1.003861)); + hpcpush(hpxyz(0.016844,-0.113094,1.006516)); + hpcpush(hpxyz(-0.010956,-0.158255,1.012504)); + hpcpush(hpxyz(-0.097643,-0.135480,1.013849)); + hpcpush(hpxyz(-0.093134,-0.099182,1.009213)); + hpcpush(hpxyz(-0.133453,-0.061874,1.010761)); + hpcpush(hpxyz(-0.131705,-0.010875,1.008694)); + hpcpush(hpxyz(-0.131705,0.010875,1.008694)); + + bshape(shHood, 43); + hpcpush(hpxyz(-0.289108,0.001285,1.040954)); + hpcpush(hpxyz(-0.253872,0.006315,1.031742)); + hpcpush(hpxyz(-0.239738,0.013807,1.028428)); + hpcpush(hpxyz(-0.225917,0.023715,1.025476)); + hpcpush(hpxyz(-0.220610,0.037392,1.024728)); + hpcpush(hpxyz(-0.239040,0.055357,1.029662)); + hpcpush(hpxyz(-0.278480,0.068016,1.040278)); + hpcpush(hpxyz(-0.290572,0.069737,1.043693)); + hpcpush(hpxyz(-0.249897,0.082453,1.034044)); + hpcpush(hpxyz(-0.220651,0.087759,1.027808)); + hpcpush(hpxyz(-0.204652,0.097335,1.025357)); + hpcpush(hpxyz(-0.243692,0.127587,1.037142)); + hpcpush(hpxyz(-0.294677,0.136206,1.051374)); + hpcpush(hpxyz(-0.303482,0.130064,1.053099)); + hpcpush(hpxyz(-0.255520,0.152279,1.043302)); + hpcpush(hpxyz(-0.227045,0.154340,1.037001)); + hpcpush(hpxyz(-0.176957,0.161897,1.028360)); + hpcpush(hpxyz(-0.131265,0.160986,1.021346)); + hpcpush(hpxyz(-0.098249,0.157199,1.017037)); + hpcpush(hpxyz(-0.054857,0.153598,1.013214)); + hpcpush(hpxyz(-0.031595,0.149471,1.011603)); + hpcpush(hpxyz(-0.001208,0.130439,1.008472)); + hpcpush(hpxyz(0.016853,0.115564,1.006796)); + hpcpush(hpxyz(0.028853,0.106995,1.006121)); + hpcpush(hpxyz(0.043228,0.096063,1.005533)); + hpcpush(hpxyz(0.053964,0.082746,1.004868)); + hpcpush(hpxyz(0.056228,0.064603,1.003661)); + hpcpush(hpxyz(0.063348,0.049005,1.003202)); + hpcpush(hpxyz(0.054927,0.048957,1.002703)); + hpcpush(hpxyz(0.014325,0.070433,1.002580)); + hpcpush(hpxyz(-0.046699,0.077832,1.004111)); + hpcpush(hpxyz(-0.088908,0.061274,1.005813)); + hpcpush(hpxyz(-0.081520,0.052748,1.004703)); + hpcpush(hpxyz(-0.044233,0.068142,1.003294)); + hpcpush(hpxyz(0.011920,0.059602,1.001846)); + hpcpush(hpxyz(0.086263,0.037141,1.004401)); + hpcpush(hpxyz(0.086263,-0.037141,1.004401)); + hpcpush(hpxyz(0.011920,-0.059602,1.001846)); + hpcpush(hpxyz(-0.044233,-0.068142,1.003294)); + hpcpush(hpxyz(-0.081520,-0.052748,1.004703)); + hpcpush(hpxyz(-0.088908,-0.061274,1.005813)); + hpcpush(hpxyz(-0.046699,-0.077832,1.004111)); + hpcpush(hpxyz(0.014325,-0.070433,1.002580)); + hpcpush(hpxyz(0.054927,-0.048957,1.002703)); + hpcpush(hpxyz(0.063348,-0.049005,1.003202)); + hpcpush(hpxyz(0.056228,-0.064603,1.003661)); + hpcpush(hpxyz(0.053964,-0.082746,1.004868)); + hpcpush(hpxyz(0.043228,-0.096063,1.005533)); + hpcpush(hpxyz(0.028853,-0.106995,1.006121)); + hpcpush(hpxyz(0.016853,-0.115564,1.006796)); + hpcpush(hpxyz(-0.001208,-0.130439,1.008472)); + hpcpush(hpxyz(-0.031595,-0.149471,1.011603)); + hpcpush(hpxyz(-0.054857,-0.153598,1.013214)); + hpcpush(hpxyz(-0.098249,-0.157199,1.017037)); + hpcpush(hpxyz(-0.131265,-0.160986,1.021346)); + hpcpush(hpxyz(-0.176957,-0.161897,1.028360)); + hpcpush(hpxyz(-0.227045,-0.154340,1.037001)); + hpcpush(hpxyz(-0.255520,-0.152279,1.043302)); + hpcpush(hpxyz(-0.303482,-0.130064,1.053099)); + hpcpush(hpxyz(-0.294677,-0.136206,1.051374)); + hpcpush(hpxyz(-0.243692,-0.127587,1.037142)); + hpcpush(hpxyz(-0.204652,-0.097335,1.025357)); + hpcpush(hpxyz(-0.220651,-0.087759,1.027808)); + hpcpush(hpxyz(-0.249897,-0.082453,1.034044)); + hpcpush(hpxyz(-0.290572,-0.069737,1.043693)); + hpcpush(hpxyz(-0.278480,-0.068016,1.040278)); + hpcpush(hpxyz(-0.239040,-0.055357,1.029662)); + hpcpush(hpxyz(-0.220610,-0.037392,1.024728)); + hpcpush(hpxyz(-0.225917,-0.023715,1.025476)); + hpcpush(hpxyz(-0.239738,-0.013807,1.028428)); + hpcpush(hpxyz(-0.253872,-0.006315,1.031742)); + hpcpush(hpxyz(-0.289108,-0.001285,1.040954)); + hpcpush(hpxyz(-0.289108,0.001285,1.040954)); + + bshape(shPHead, 44); + hpcpush(hpxyz(0.060794,0.001192,1.001847)); + hpcpush(hpxyz(0.058426,0.023847,1.001989)); + hpcpush(hpxyz(0.050054,0.030986,1.001731)); + hpcpush(hpxyz(0.042896,0.038130,1.001646)); + hpcpush(hpxyz(0.044109,0.042917,1.001892)); + hpcpush(hpxyz(0.032180,0.050058,1.001769)); + hpcpush(hpxyz(0.017884,0.059612,1.001935)); + hpcpush(hpxyz(0.005963,0.064401,1.002089)); + hpcpush(hpxyz(-0.009546,0.068015,1.002356)); + hpcpush(hpxyz(-0.022689,0.070455,1.002736)); + hpcpush(hpxyz(-0.044247,0.070556,1.003462)); + hpcpush(hpxyz(-0.053847,0.068206,1.003769)); + hpcpush(hpxyz(-0.047819,0.065752,1.003300)); + hpcpush(hpxyz(-0.040573,0.056087,1.002393)); + hpcpush(hpxyz(-0.040563,0.053686,1.002261)); + hpcpush(hpxyz(-0.053753,0.053753,1.002885)); + hpcpush(hpxyz(-0.067016,0.056246,1.003820)); + hpcpush(hpxyz(-0.090053,0.054032,1.005499)); + hpcpush(hpxyz(-0.097365,0.051688,1.006057)); + hpcpush(hpxyz(-0.072989,0.046665,1.003746)); + hpcpush(hpxyz(-0.065710,0.040621,1.002979)); + hpcpush(hpxyz(-0.063272,0.034621,1.002598)); + hpcpush(hpxyz(-0.064461,0.031037,1.002556)); + hpcpush(hpxyz(-0.074098,0.028683,1.003152)); + hpcpush(hpxyz(-0.094756,0.031185,1.004963)); + hpcpush(hpxyz(-0.113149,0.027685,1.006762)); + hpcpush(hpxyz(-0.114376,0.026487,1.006868)); + hpcpush(hpxyz(-0.088611,0.020357,1.004125)); + hpcpush(hpxyz(-0.087387,0.017956,1.003972)); + hpcpush(hpxyz(-0.103257,0.018010,1.005478)); + hpcpush(hpxyz(-0.127970,0.014487,1.008259)); + hpcpush(hpxyz(-0.164656,0.006098,1.013484)); + hpcpush(hpxyz(-0.174996,0.001224,1.015197)); + hpcpush(hpxyz(-0.174996,-0.001224,1.015197)); + hpcpush(hpxyz(-0.164656,-0.006098,1.013484)); + hpcpush(hpxyz(-0.127970,-0.014487,1.008259)); + hpcpush(hpxyz(-0.103257,-0.018010,1.005478)); + hpcpush(hpxyz(-0.087387,-0.017956,1.003972)); + hpcpush(hpxyz(-0.088611,-0.020357,1.004125)); + hpcpush(hpxyz(-0.114376,-0.026487,1.006868)); + hpcpush(hpxyz(-0.113149,-0.027685,1.006762)); + hpcpush(hpxyz(-0.094756,-0.031185,1.004963)); + hpcpush(hpxyz(-0.074098,-0.028683,1.003152)); + hpcpush(hpxyz(-0.064461,-0.031037,1.002556)); + hpcpush(hpxyz(-0.063272,-0.034621,1.002598)); + hpcpush(hpxyz(-0.065710,-0.040621,1.002979)); + hpcpush(hpxyz(-0.072989,-0.046665,1.003746)); + hpcpush(hpxyz(-0.097365,-0.051688,1.006057)); + hpcpush(hpxyz(-0.090053,-0.054032,1.005499)); + hpcpush(hpxyz(-0.067016,-0.056246,1.003820)); + hpcpush(hpxyz(-0.053753,-0.053753,1.002885)); + hpcpush(hpxyz(-0.040563,-0.053686,1.002261)); + hpcpush(hpxyz(-0.040573,-0.056087,1.002393)); + hpcpush(hpxyz(-0.047819,-0.065752,1.003300)); + hpcpush(hpxyz(-0.053847,-0.068206,1.003769)); + hpcpush(hpxyz(-0.044247,-0.070556,1.003462)); + hpcpush(hpxyz(-0.022689,-0.070455,1.002736)); + hpcpush(hpxyz(-0.009546,-0.068015,1.002356)); + hpcpush(hpxyz(0.005963,-0.064401,1.002089)); + hpcpush(hpxyz(0.017884,-0.059612,1.001935)); + hpcpush(hpxyz(0.032180,-0.050058,1.001769)); + hpcpush(hpxyz(0.044109,-0.042917,1.001892)); + hpcpush(hpxyz(0.042896,-0.038130,1.001646)); + hpcpush(hpxyz(0.050054,-0.030986,1.001731)); + hpcpush(hpxyz(0.058426,-0.023847,1.001989)); + hpcpush(hpxyz(0.060794,-0.001192,1.001847)); + hpcpush(hpxyz(0.060794,0.001192,1.001847)); + + shGolemhead = shDisk; shGolemhead.prio = 43; + + bshape(shFemaleHair, 44); + hpcpush(hpxyz(-0.185924,0.002463,1.017140)); + hpcpush(hpxyz(-0.273576,0.019176,1.036924)); + hpcpush(hpxyz(-0.186050,0.025874,1.017489)); + hpcpush(hpxyz(-0.268509,0.057538,1.037019)); + hpcpush(hpxyz(-0.183840,0.054288,1.018206)); + hpcpush(hpxyz(-0.258480,0.097250,1.037434)); + hpcpush(hpxyz(-0.174976,0.069005,1.017535)); + hpcpush(hpxyz(-0.246145,0.133329,1.038443)); + hpcpush(hpxyz(0.029891,0.058585,1.002161)); + hpcpush(hpxyz(0.045415,0.043025,1.001955)); + hpcpush(hpxyz(0.051358,0.025082,1.001632)); + hpcpush(hpxyz(0.051358,-0.025082,1.001632)); + hpcpush(hpxyz(0.045415,-0.043025,1.001955)); + hpcpush(hpxyz(0.029891,-0.058585,1.002161)); + hpcpush(hpxyz(-0.246145,-0.133329,1.038443)); + hpcpush(hpxyz(-0.174976,-0.069005,1.017535)); + hpcpush(hpxyz(-0.258480,-0.097250,1.037434)); + hpcpush(hpxyz(-0.183840,-0.054288,1.018206)); + hpcpush(hpxyz(-0.268509,-0.057538,1.037019)); + hpcpush(hpxyz(-0.186050,-0.025874,1.017489)); + hpcpush(hpxyz(-0.273576,-0.019176,1.036924)); + hpcpush(hpxyz(-0.185924,-0.002463,1.017140)); + hpcpush(hpxyz(-0.185924,0.002463,1.017140)); + + bshape(shPFace, 45); + hpcpush(hpxyz(0.011878,-0.000000,1.000071)); + hpcpush(hpxyz(0.011880,0.010692,1.000128)); + hpcpush(hpxyz(0.014262,0.022581,1.000357)); + hpcpush(hpxyz(0.015455,0.027343,1.000493)); + hpcpush(hpxyz(0.017842,0.034494,1.000754)); + hpcpush(hpxyz(0.021425,0.041659,1.001097)); + hpcpush(hpxyz(0.025005,0.044056,1.001282)); + hpcpush(hpxyz(0.029785,0.047656,1.001578)); + hpcpush(hpxyz(0.032176,0.048860,1.001710)); + hpcpush(hpxyz(0.036964,0.051273,1.001996)); + hpcpush(hpxyz(0.044133,0.048905,1.002167)); + hpcpush(hpxyz(0.046519,0.046519,1.002162)); + hpcpush(hpxyz(0.051292,0.041749,1.002185)); + hpcpush(hpxyz(0.056061,0.034591,1.002167)); + hpcpush(hpxyz(0.060844,0.028632,1.002258)); + hpcpush(hpxyz(0.064425,0.020282,1.002278)); + hpcpush(hpxyz(0.064417,0.016701,1.002212)); + hpcpush(hpxyz(0.069220,0.009548,1.002438)); + hpcpush(hpxyz(0.075246,0.003583,1.002833)); + hpcpush(hpxyz(0.077662,0.001195,1.003012)); + hpcpush(hpxyz(0.080082,-0.000000,1.003201)); + hpcpush(hpxyz(0.080082,0.000000,1.003201)); + hpcpush(hpxyz(0.077662,-0.001195,1.003012)); + hpcpush(hpxyz(0.075246,-0.003583,1.002833)); + hpcpush(hpxyz(0.069220,-0.009548,1.002438)); + hpcpush(hpxyz(0.064417,-0.016701,1.002212)); + hpcpush(hpxyz(0.064425,-0.020282,1.002278)); + hpcpush(hpxyz(0.060844,-0.028632,1.002258)); + hpcpush(hpxyz(0.056061,-0.034591,1.002167)); + hpcpush(hpxyz(0.051292,-0.041749,1.002185)); + hpcpush(hpxyz(0.046519,-0.046519,1.002162)); + hpcpush(hpxyz(0.044133,-0.048905,1.002167)); + hpcpush(hpxyz(0.036964,-0.051273,1.001996)); + hpcpush(hpxyz(0.032176,-0.048860,1.001710)); + hpcpush(hpxyz(0.029785,-0.047656,1.001578)); + hpcpush(hpxyz(0.025005,-0.044056,1.001282)); + hpcpush(hpxyz(0.021425,-0.041659,1.001097)); + hpcpush(hpxyz(0.017842,-0.034494,1.000754)); + hpcpush(hpxyz(0.015455,-0.027343,1.000493)); + hpcpush(hpxyz(0.014262,-0.022581,1.000357)); + hpcpush(hpxyz(0.011880,-0.010692,1.000128)); + hpcpush(hpxyz(0.011878,0.000000,1.000071)); + hpcpush(hpxyz(0.011878,-0.000000,1.000071)); + + bshape(shEyes, 46); + hpcpush(hpxyz(0.070467,0.026276,1.002824)); + hpcpush(hpxyz(0.054837,0.027418,1.001878)); + hpcpush(hpxyz(0.040494,0.034539,1.001415)); + hpcpush(hpxyz(0.034561,0.047670,1.001732)); + hpcpush(hpxyz(0.032259,0.070492,1.003000)); + hpcpush(hpxyz(0.044434,0.096073,1.005587)); + hpcpush(hpxyz(0.065124,0.106127,1.007722)); + hpcpush(hpxyz(0.089628,0.109007,1.009909)); + hpcpush(hpxyz(0.110425,0.098291,1.010868)); + hpcpush(hpxyz(0.121434,0.088647,1.011239)); + hpcpush(hpxyz(0.124892,0.073965,1.010479)); + hpcpush(hpxyz(0.123474,0.064158,1.009635)); + hpcpush(hpxyz(0.117069,0.050690,1.008104)); + hpcpush(hpxyz(0.113313,0.047013,1.007497)); + hpcpush(hpxyz(0.098463,0.037224,1.005525)); + hpcpush(hpxyz(0.081366,0.029914,1.003751)); + hpcpush(hpxyz(0.070467,0.026276,1.002824)); + hpcpush(hpxyz(0.070467,-0.026276,1.002824)); + hpcpush(hpxyz(0.081366,-0.029914,1.003751)); + hpcpush(hpxyz(0.098463,-0.037224,1.005525)); + hpcpush(hpxyz(0.113313,-0.047013,1.007497)); + hpcpush(hpxyz(0.117069,-0.050690,1.008104)); + hpcpush(hpxyz(0.123474,-0.064158,1.009635)); + hpcpush(hpxyz(0.124892,-0.073965,1.010479)); + hpcpush(hpxyz(0.121434,-0.088647,1.011239)); + hpcpush(hpxyz(0.110425,-0.098291,1.010868)); + hpcpush(hpxyz(0.089628,-0.109007,1.009909)); + hpcpush(hpxyz(0.065124,-0.106127,1.007722)); + hpcpush(hpxyz(0.044434,-0.096073,1.005587)); + hpcpush(hpxyz(0.032259,-0.070492,1.003000)); + hpcpush(hpxyz(0.034561,-0.047670,1.001732)); + hpcpush(hpxyz(0.040494,-0.034539,1.001415)); + hpcpush(hpxyz(0.054837,-0.027418,1.001878)); + hpcpush(hpxyz(0.070467,-0.026276,1.002824)); + hpcpush(hpxyz(0.070467,0.026276,1.002824)); + + bshape(shShark, 47); + hpcpush(hpxyz(-0.254548,0.002533,1.031892)); + hpcpush(hpxyz(-0.295445,0.115041,1.049058)); + hpcpush(hpxyz(-0.214304,0.034887,1.023300)); + hpcpush(hpxyz(-0.113418,0.026545,1.006761)); + hpcpush(hpxyz(-0.034699,0.062219,1.002534)); + hpcpush(hpxyz(-0.010782,0.079071,1.003179)); + hpcpush(hpxyz(0.009598,0.087578,1.003874)); + hpcpush(hpxyz(0.037297,0.096250,1.005313)); + hpcpush(hpxyz(-0.001207,0.119535,1.007120)); + hpcpush(hpxyz(-0.032645,0.120908,1.007812)); + hpcpush(hpxyz(-0.002431,0.144615,1.010406)); + hpcpush(hpxyz(0.027983,0.145997,1.010989)); + hpcpush(hpxyz(0.058411,0.137510,1.011099)); + hpcpush(hpxyz(0.096163,0.115639,1.011247)); + hpcpush(hpxyz(0.130542,0.089062,1.012410)); + hpcpush(hpxyz(0.175135,0.075234,1.018004)); + hpcpush(hpxyz(0.227410,0.066590,1.027691)); + hpcpush(hpxyz(0.215688,0.036156,1.023635)); + hpcpush(hpxyz(0.187577,0.041958,1.018305)); + hpcpush(hpxyz(0.184662,0.017235,1.017053)); + hpcpush(hpxyz(0.208627,0.008693,1.021568)); + hpcpush(hpxyz(0.214217,0.028645,1.023088)); + hpcpush(hpxyz(0.229902,0.056533,1.027643)); + hpcpush(hpxyz(0.249359,0.045568,1.031628)); + hpcpush(hpxyz(0.259206,0.035577,1.033660)); + hpcpush(hpxyz(0.276638,0.026895,1.037908)); + hpcpush(hpxyz(0.302288,0.020758,1.044897)); + hpcpush(hpxyz(0.330687,0.013175,1.053341)); + hpcpush(hpxyz(0.348759,-0.003993,1.059079)); + hpcpush(hpxyz(0.348759,0.003993,1.059079)); + hpcpush(hpxyz(0.330687,-0.013175,1.053341)); + hpcpush(hpxyz(0.302288,-0.020758,1.044897)); + hpcpush(hpxyz(0.276638,-0.026895,1.037908)); + hpcpush(hpxyz(0.259206,-0.035577,1.033660)); + hpcpush(hpxyz(0.249359,-0.045568,1.031628)); + hpcpush(hpxyz(0.229902,-0.056533,1.027643)); + hpcpush(hpxyz(0.214217,-0.028645,1.023088)); + hpcpush(hpxyz(0.208627,-0.008693,1.021568)); + hpcpush(hpxyz(0.184662,-0.017235,1.017053)); + hpcpush(hpxyz(0.187577,-0.041958,1.018305)); + hpcpush(hpxyz(0.215688,-0.036156,1.023635)); + hpcpush(hpxyz(0.227410,-0.066590,1.027691)); + hpcpush(hpxyz(0.175135,-0.075234,1.018004)); + hpcpush(hpxyz(0.130542,-0.089062,1.012410)); + hpcpush(hpxyz(0.096163,-0.115639,1.011247)); + hpcpush(hpxyz(0.058411,-0.137510,1.011099)); + hpcpush(hpxyz(0.027983,-0.145997,1.010989)); + hpcpush(hpxyz(-0.002431,-0.144615,1.010406)); + hpcpush(hpxyz(-0.032645,-0.120908,1.007812)); + hpcpush(hpxyz(-0.001207,-0.119535,1.007120)); + hpcpush(hpxyz(0.037297,-0.096250,1.005313)); + hpcpush(hpxyz(0.009598,-0.087578,1.003874)); + hpcpush(hpxyz(-0.010782,-0.079071,1.003179)); + hpcpush(hpxyz(-0.034699,-0.062219,1.002534)); + hpcpush(hpxyz(-0.113418,-0.026545,1.006761)); + hpcpush(hpxyz(-0.214304,-0.034887,1.023300)); + hpcpush(hpxyz(-0.295445,-0.115041,1.049058)); + hpcpush(hpxyz(-0.254548,-0.002533,1.031892)); + hpcpush(hpxyz(-0.254548,0.002533,1.031892)); + + bshape(shBugBody, 33); + hpcpush(hpxyz(-0.036973,0.000272,1.000683)); + hpcpush(hpxyz(-0.037088,0.049282,1.001900)); + hpcpush(hpxyz(-0.103861,0.110700,1.011455)); + hpcpush(hpxyz(-0.187497,0.070862,1.019891)); + hpcpush(hpxyz(-0.199435,0.092353,1.023867)); + hpcpush(hpxyz(-0.102619,0.135884,1.014394)); + hpcpush(hpxyz(-0.010856,0.052276,1.001424)); + hpcpush(hpxyz(0.027094,0.127840,1.008502)); + hpcpush(hpxyz(-0.010117,0.161004,1.012929)); + hpcpush(hpxyz(-0.122621,0.155285,1.019387)); + hpcpush(hpxyz(-0.129838,0.187041,1.025593)); + hpcpush(hpxyz(-0.003559,0.192507,1.018367)); + hpcpush(hpxyz(0.048774,0.146275,1.011818)); + hpcpush(hpxyz(0.045625,0.106117,1.006649)); + hpcpush(hpxyz(0.010970,0.038441,1.000799)); + hpcpush(hpxyz(0.089547,0.116575,1.010746)); + hpcpush(hpxyz(0.094553,0.161297,1.017328)); + hpcpush(hpxyz(0.079585,0.174794,1.018276)); + hpcpush(hpxyz(0.010872,0.213071,1.022505)); + hpcpush(hpxyz(0.019129,0.245278,1.029819)); + hpcpush(hpxyz(0.122810,0.186751,1.024675)); + hpcpush(hpxyz(0.134973,0.146945,1.019711)); + hpcpush(hpxyz(0.133411,0.118806,1.015831)); + hpcpush(hpxyz(0.060081,0.038600,1.002547)); + hpcpush(hpxyz(0.122451,0.041792,1.008336)); + hpcpush(hpxyz(0.137147,0.087747,1.013168)); + hpcpush(hpxyz(0.150029,0.114701,1.017676)); + hpcpush(hpxyz(0.172516,0.135274,1.023748)); + hpcpush(hpxyz(0.194165,0.144658,1.028896)); + hpcpush(hpxyz(0.206227,0.137750,1.030293)); + hpcpush(hpxyz(0.191047,0.128830,1.026205)); + hpcpush(hpxyz(0.173558,0.119946,1.022012)); + hpcpush(hpxyz(0.156400,0.103721,1.017457)); + hpcpush(hpxyz(0.146061,0.085696,1.014237)); + hpcpush(hpxyz(0.131320,0.034801,1.009186)); + hpcpush(hpxyz(0.128188,0.004402,1.008192)); + hpcpush(hpxyz(0.128188,-0.004402,1.008192)); + hpcpush(hpxyz(0.131320,-0.034801,1.009186)); + hpcpush(hpxyz(0.146061,-0.085696,1.014237)); + hpcpush(hpxyz(0.156400,-0.103721,1.017457)); + hpcpush(hpxyz(0.173558,-0.119946,1.022012)); + hpcpush(hpxyz(0.191047,-0.128830,1.026205)); + hpcpush(hpxyz(0.206227,-0.137750,1.030293)); + hpcpush(hpxyz(0.194165,-0.144658,1.028896)); + hpcpush(hpxyz(0.172516,-0.135274,1.023748)); + hpcpush(hpxyz(0.150029,-0.114701,1.017676)); + hpcpush(hpxyz(0.137147,-0.087747,1.013168)); + hpcpush(hpxyz(0.122451,-0.041792,1.008336)); + hpcpush(hpxyz(0.060081,-0.038600,1.002547)); + hpcpush(hpxyz(0.133411,-0.118806,1.015831)); + hpcpush(hpxyz(0.134973,-0.146945,1.019711)); + hpcpush(hpxyz(0.122810,-0.186751,1.024675)); + hpcpush(hpxyz(0.019129,-0.245278,1.029819)); + hpcpush(hpxyz(0.010872,-0.213071,1.022505)); + hpcpush(hpxyz(0.079585,-0.174794,1.018276)); + hpcpush(hpxyz(0.094553,-0.161297,1.017328)); + hpcpush(hpxyz(0.089547,-0.116575,1.010746)); + hpcpush(hpxyz(0.010970,-0.038441,1.000799)); + hpcpush(hpxyz(0.045625,-0.106117,1.006649)); + hpcpush(hpxyz(0.048774,-0.146275,1.011818)); + hpcpush(hpxyz(-0.003559,-0.192507,1.018367)); + hpcpush(hpxyz(-0.129838,-0.187041,1.025593)); + hpcpush(hpxyz(-0.122621,-0.155285,1.019387)); + hpcpush(hpxyz(-0.010117,-0.161004,1.012929)); + hpcpush(hpxyz(0.027094,-0.127840,1.008502)); + hpcpush(hpxyz(-0.010856,-0.052276,1.001424)); + hpcpush(hpxyz(-0.102619,-0.135884,1.014394)); + hpcpush(hpxyz(-0.199435,-0.092353,1.023867)); + hpcpush(hpxyz(-0.187497,-0.070862,1.019891)); + hpcpush(hpxyz(-0.103861,-0.110700,1.011455)); + hpcpush(hpxyz(-0.037088,-0.049282,1.001900)); + hpcpush(hpxyz(-0.036973,-0.000272,1.000683)); + hpcpush(hpxyz(-0.036973,0.000272,1.000683)); + + bshape(shBugArmor, 34); + hpcpush(hpxyz(-0.257478,-0.001337,1.032616)); + hpcpush(hpxyz(-0.204917,0.009783,1.020827)); + hpcpush(hpxyz(-0.203815,0.017248,1.020705)); + hpcpush(hpxyz(-0.113586,0.008028,1.006462)); + hpcpush(hpxyz(-0.187093,0.033579,1.017905)); + hpcpush(hpxyz(-0.182177,0.042285,1.017338)); + hpcpush(hpxyz(-0.170953,0.054731,1.015982)); + hpcpush(hpxyz(-0.148063,0.061036,1.012743)); + hpcpush(hpxyz(-0.114175,0.062548,1.008439)); + hpcpush(hpxyz(-0.089190,0.053147,1.005375)); + hpcpush(hpxyz(-0.055805,0.032092,1.002070)); + hpcpush(hpxyz(-0.046611,0.046680,1.002173)); + hpcpush(hpxyz(-0.034899,0.056544,1.002205)); + hpcpush(hpxyz(-0.026686,0.062743,1.002322)); + hpcpush(hpxyz(-0.011200,0.065507,1.002206)); + hpcpush(hpxyz(0.015073,0.067380,1.002381)); + hpcpush(hpxyz(0.038084,0.055978,1.002289)); + hpcpush(hpxyz(0.058951,0.034968,1.002346)); + hpcpush(hpxyz(0.080396,0.053686,1.004662)); + hpcpush(hpxyz(0.091257,0.062541,1.006101)); + hpcpush(hpxyz(0.107216,0.066788,1.007946)); + hpcpush(hpxyz(0.136013,0.061816,1.011099)); + hpcpush(hpxyz(0.150105,0.048890,1.012384)); + hpcpush(hpxyz(0.154042,0.040462,1.012604)); + hpcpush(hpxyz(0.173238,0.060925,1.016722)); + hpcpush(hpxyz(0.190355,0.071679,1.020477)); + hpcpush(hpxyz(0.214645,0.070389,1.025196)); + hpcpush(hpxyz(0.221506,0.066951,1.026424)); + hpcpush(hpxyz(0.203766,0.058557,1.022228)); + hpcpush(hpxyz(0.189101,0.049201,1.018911)); + hpcpush(hpxyz(0.181298,0.037761,1.017003)); + hpcpush(hpxyz(0.177552,0.025312,1.015955)); + hpcpush(hpxyz(0.177715,0.016710,1.015806)); + hpcpush(hpxyz(0.176915,-0.004189,1.015537)); + hpcpush(hpxyz(0.176915,0.004189,1.015537)); + hpcpush(hpxyz(0.177715,-0.016710,1.015806)); + hpcpush(hpxyz(0.177552,-0.025312,1.015955)); + hpcpush(hpxyz(0.181298,-0.037761,1.017003)); + hpcpush(hpxyz(0.189101,-0.049201,1.018911)); + hpcpush(hpxyz(0.203766,-0.058557,1.022228)); + hpcpush(hpxyz(0.221506,-0.066951,1.026424)); + hpcpush(hpxyz(0.214645,-0.070389,1.025196)); + hpcpush(hpxyz(0.190355,-0.071679,1.020477)); + hpcpush(hpxyz(0.173238,-0.060925,1.016722)); + hpcpush(hpxyz(0.154042,-0.040462,1.012604)); + hpcpush(hpxyz(0.150105,-0.048890,1.012384)); + hpcpush(hpxyz(0.136013,-0.061816,1.011099)); + hpcpush(hpxyz(0.107216,-0.066788,1.007946)); + hpcpush(hpxyz(0.091257,-0.062541,1.006101)); + hpcpush(hpxyz(0.080396,-0.053686,1.004662)); + hpcpush(hpxyz(0.058951,-0.034968,1.002346)); + hpcpush(hpxyz(0.038084,-0.055978,1.002289)); + hpcpush(hpxyz(0.015073,-0.067380,1.002381)); + hpcpush(hpxyz(-0.011200,-0.065507,1.002206)); + hpcpush(hpxyz(-0.026686,-0.062743,1.002322)); + hpcpush(hpxyz(-0.034899,-0.056544,1.002205)); + hpcpush(hpxyz(-0.046611,-0.046680,1.002173)); + hpcpush(hpxyz(-0.055805,-0.032092,1.002070)); + hpcpush(hpxyz(-0.089190,-0.053147,1.005375)); + hpcpush(hpxyz(-0.114175,-0.062548,1.008439)); + hpcpush(hpxyz(-0.148063,-0.061036,1.012743)); + hpcpush(hpxyz(-0.170953,-0.054731,1.015982)); + hpcpush(hpxyz(-0.182177,-0.042285,1.017338)); + hpcpush(hpxyz(-0.187093,-0.033579,1.017905)); + hpcpush(hpxyz(-0.113586,-0.008028,1.006462)); + hpcpush(hpxyz(-0.203815,-0.017248,1.020705)); + hpcpush(hpxyz(-0.204917,-0.009783,1.020827)); + hpcpush(hpxyz(-0.257478,0.001337,1.032616)); + hpcpush(hpxyz(-0.257478,-0.001337,1.032616)); + + bshape(shWolfBody, 33); + hpcpush(hwolf(-0.311492,0.001303,1.047391)); + hpcpush(hwolf(-0.165080,0.009783,1.013581)); + hpcpush(hwolf(-0.195342,0.027200,1.019264)); + hpcpush(hwolf(-0.153616,0.025603,1.012054)); + hpcpush(hwolf(-0.173302,0.051622,1.016218)); + hpcpush(hwolf(-0.128440,0.037563,1.008914)); + hpcpush(hwolf(-0.152961,0.068527,1.013949)); + hpcpush(hwolf(-0.107392,0.045853,1.006795)); + hpcpush(hwolf(-0.121764,0.090105,1.011408)); + hpcpush(hwolf(-0.079263,0.050440,1.004404)); + hpcpush(hwolf(-0.084555,0.086971,1.007330)); + hpcpush(hwolf(-0.043029,0.046615,1.002010)); + hpcpush(hwolf(-0.049440,0.102497,1.006454)); + hpcpush(hwolf(-0.020293,0.047747,1.001345)); + hpcpush(hwolf(-0.012028,0.101033,1.005163)); + hpcpush(hwolf(0.009546,0.047732,1.001184)); + hpcpush(hwolf(0.027630,0.091298,1.004539)); + hpcpush(hwolf(0.043025,0.045415,1.001955)); + hpcpush(hwolf(0.071007,0.077024,1.005472)); + hpcpush(hwolf(0.071856,0.028742,1.002990)); + hpcpush(hwolf(0.113578,0.045915,1.007476)); + hpcpush(hwolf(0.090012,0.007201,1.004069)); + hpcpush(hwolf(0.090012,-0.007201,1.004069)); + hpcpush(hwolf(0.113578,-0.045915,1.007476)); + hpcpush(hwolf(0.071856,-0.028742,1.002990)); + hpcpush(hwolf(0.071007,-0.077024,1.005472)); + hpcpush(hwolf(0.043025,-0.045415,1.001955)); + hpcpush(hwolf(0.027630,-0.091298,1.004539)); + hpcpush(hwolf(0.009546,-0.047732,1.001184)); + hpcpush(hwolf(-0.012028,-0.101033,1.005163)); + hpcpush(hwolf(-0.020293,-0.047747,1.001345)); + hpcpush(hwolf(-0.049440,-0.102497,1.006454)); + hpcpush(hwolf(-0.043029,-0.046615,1.002010)); + hpcpush(hwolf(-0.084555,-0.086971,1.007330)); + hpcpush(hwolf(-0.079263,-0.050440,1.004404)); + hpcpush(hwolf(-0.121764,-0.090105,1.011408)); + hpcpush(hwolf(-0.107392,-0.045853,1.006795)); + hpcpush(hwolf(-0.152961,-0.068527,1.013949)); + hpcpush(hwolf(-0.128440,-0.037563,1.008914)); + hpcpush(hwolf(-0.173302,-0.051622,1.016218)); + hpcpush(hwolf(-0.153616,-0.025603,1.012054)); + hpcpush(hwolf(-0.195342,-0.027200,1.019264)); + hpcpush(hwolf(-0.165080,-0.009783,1.013581)); + hpcpush(hwolf(-0.311492,-0.001303,1.047391)); + hpcpush(hwolf(-0.311492,0.001303,1.047391)); + + bshape(shWolfHead, 34); + hpcpush(hwolf(0.183292,0.002460,1.016662)); + hpcpush(hwolf(0.178071,0.011053,1.015791)); + hpcpush(hwolf(0.185996,0.019708,1.017341)); + hpcpush(hwolf(0.170281,0.015926,1.014519)); + hpcpush(hwolf(0.170341,0.024510,1.014700)); + hpcpush(hwolf(0.158693,0.019531,1.012702)); + hpcpush(hwolf(0.158807,0.032983,1.013068)); + hpcpush(hwolf(0.147214,0.020683,1.010989)); + hpcpush(hwolf(0.142274,0.036481,1.010729)); + hpcpush(hwolf(0.135869,0.025475,1.009510)); + hpcpush(hwolf(0.129693,0.037575,1.009075)); + hpcpush(hwolf(0.118394,0.028994,1.007401)); + hpcpush(hwolf(0.114793,0.043501,1.007507)); + hpcpush(hwolf(0.102362,0.033719,1.005791)); + hpcpush(hwolf(0.100073,0.053051,1.006394)); + hpcpush(hwolf(0.087692,0.037239,1.004528)); + hpcpush(hwolf(0.080602,0.063760,1.005267)); + hpcpush(hwolf(0.065828,0.032315,1.002685)); + hpcpush(hwolf(0.008362,0.058537,1.001747)); + hpcpush(hwolf(0.046539,0.014320,1.001185)); + hpcpush(hwolf(0.028597,0.008341,1.000444)); + hpcpush(hwolf(0.051325,-0.000000,1.001316)); + hpcpush(hwolf(0.051325,0.000000,1.001316)); + hpcpush(hwolf(0.028597,-0.008341,1.000444)); + hpcpush(hwolf(0.046539,-0.014320,1.001185)); + hpcpush(hwolf(0.008362,-0.058537,1.001747)); + hpcpush(hwolf(0.065828,-0.032315,1.002685)); + hpcpush(hwolf(0.080602,-0.063760,1.005267)); + hpcpush(hwolf(0.087692,-0.037239,1.004528)); + hpcpush(hwolf(0.100073,-0.053051,1.006394)); + hpcpush(hwolf(0.102362,-0.033719,1.005791)); + hpcpush(hwolf(0.114793,-0.043501,1.007507)); + hpcpush(hwolf(0.118394,-0.028994,1.007401)); + hpcpush(hwolf(0.129693,-0.037575,1.009075)); + hpcpush(hwolf(0.135869,-0.025475,1.009510)); + hpcpush(hwolf(0.142274,-0.036481,1.010729)); + hpcpush(hwolf(0.147214,-0.020683,1.010989)); + hpcpush(hwolf(0.158807,-0.032983,1.013068)); + hpcpush(hwolf(0.158693,-0.019531,1.012702)); + hpcpush(hwolf(0.170341,-0.024510,1.014700)); + hpcpush(hwolf(0.170281,-0.015926,1.014519)); + hpcpush(hwolf(0.185996,-0.019708,1.017341)); + hpcpush(hwolf(0.178071,-0.011053,1.015791)); + hpcpush(hwolf(0.183292,-0.002460,1.016662)); + hpcpush(hwolf(0.183292,0.002460,1.016662)); + + bshape(shWolfLegs, 32); + hpcpush(hwolf(-0.139559,-0.001214,1.009692)); + hpcpush(hwolf(-0.139599,0.016995,1.009840)); + hpcpush(hwolf(-0.228445,0.053973,1.027181)); + hpcpush(hwolf(-0.209280,0.056057,1.023201)); + hpcpush(hwolf(-0.216331,0.065024,1.025196)); + hpcpush(hwolf(-0.204121,0.065966,1.022750)); + hpcpush(hwolf(-0.204581,0.081084,1.023928)); + hpcpush(hwolf(-0.194817,0.069489,1.021167)); + hpcpush(hwolf(-0.113487,0.036219,1.007071)); + hpcpush(hwolf(-0.008338,0.022632,1.000291)); + hpcpush(hwolf(0.076062,0.091757,1.007077)); + hpcpush(hwolf(0.081210,0.107875,1.009075)); + hpcpush(hwolf(0.084610,0.090653,1.007659)); + hpcpush(hwolf(0.099450,0.094598,1.009376)); + hpcpush(hwolf(0.089336,0.078471,1.007045)); + hpcpush(hwolf(0.105258,0.072592,1.008141)); + hpcpush(hwolf(0.083028,0.062572,1.005390)); + hpcpush(hwolf(0.025016,0.001191,1.000314)); + hpcpush(hwolf(0.025016,-0.001191,1.000314)); + hpcpush(hwolf(0.083028,-0.062572,1.005390)); + hpcpush(hwolf(0.105258,-0.072592,1.008141)); + hpcpush(hwolf(0.089336,-0.078471,1.007045)); + hpcpush(hwolf(0.099450,-0.094598,1.009376)); + hpcpush(hwolf(0.084610,-0.090653,1.007659)); + hpcpush(hwolf(0.081210,-0.107875,1.009075)); + hpcpush(hwolf(0.076062,-0.091757,1.007077)); + hpcpush(hwolf(-0.008338,-0.022632,1.000291)); + hpcpush(hwolf(-0.113487,-0.036219,1.007071)); + hpcpush(hwolf(-0.194817,-0.069489,1.021167)); + hpcpush(hwolf(-0.204581,-0.081084,1.023928)); + hpcpush(hwolf(-0.204121,-0.065966,1.022750)); + hpcpush(hwolf(-0.216331,-0.065024,1.025196)); + hpcpush(hwolf(-0.209280,-0.056057,1.023201)); + hpcpush(hwolf(-0.228445,-0.053973,1.027181)); + hpcpush(hwolf(-0.139599,-0.016995,1.009840)); + hpcpush(hwolf(-0.139559,0.001214,1.009692)); + hpcpush(hwolf(-0.139559,-0.001214,1.009692)); + + // group 2 layer 3 + + bshape(shWolfEyes, 35); + hpcpush(hwolf(0.172835,0.002452,1.014829)); + hpcpush(hwolf(0.156071,0.002439,1.012109)); + hpcpush(hwolf(0.154815,0.012190,1.011986)); + hpcpush(hwolf(0.138338,0.016989,1.009666)); + hpcpush(hwolf(0.135790,0.008487,1.009213)); + hpcpush(hwolf(0.147155,0.006081,1.010788)); + hpcpush(hwolf(0.153518,0.004874,1.011727)); + hpcpush(hwolf(0.156070,-0.000000,1.012106)); + hpcpush(hwolf(0.156070,0.000000,1.012106)); + hpcpush(hwolf(0.153518,-0.004874,1.011727)); + hpcpush(hwolf(0.147155,-0.006081,1.010788)); + hpcpush(hwolf(0.135790,-0.008487,1.009213)); + hpcpush(hwolf(0.138338,-0.016989,1.009666)); + hpcpush(hwolf(0.154815,-0.012190,1.011986)); + hpcpush(hwolf(0.156071,-0.002439,1.012109)); + hpcpush(hwolf(0.172835,-0.002452,1.014829)); + hpcpush(hwolf(0.172835,0.002452,1.014829)); + + // Witch's Dress + + bshape(shWitchDress, 42); + hpcpush(hpxyz(0.039326,-0.001751,1.000774)); + hpcpush(hpxyz(0.041168,0.053278,1.002264)); + hpcpush(hpxyz(0.035516,0.073044,1.003293)); + hpcpush(hpxyz(0.024685,0.088439,1.004207)); + hpcpush(hpxyz(0.009671,0.096889,1.004729)); + hpcpush(hpxyz(-0.002313,0.097795,1.004773)); + hpcpush(hpxyz(-0.008219,0.099482,1.004970)); + hpcpush(hpxyz(-0.016102,0.107500,1.005890)); + hpcpush(hpxyz(-0.016016,0.108729,1.006021)); + hpcpush(hpxyz(-0.022078,0.163499,1.013518)); + hpcpush(hpxyz(-0.052858,0.141939,1.011405)); + hpcpush(hpxyz(-0.084069,0.161675,1.016468)); + hpcpush(hpxyz(-0.098088,0.129874,1.013158)); + hpcpush(hpxyz(-0.108494,0.122098,1.013252)); + hpcpush(hpxyz(-0.117272,0.122997,1.014338)); + hpcpush(hpxyz(-0.128424,0.129237,1.016462)); + hpcpush(hpxyz(-0.140905,0.138269,1.019300)); + hpcpush(hpxyz(-0.152175,0.151195,1.022750)); + hpcpush(hpxyz(-0.161208,0.157511,1.025084)); + hpcpush(hpxyz(-0.178346,0.167608,1.029514)); + hpcpush(hpxyz(-0.195945,0.176675,1.034219)); + hpcpush(hpxyz(-0.219689,0.185527,1.040521)); + hpcpush(hpxyz(-0.234056,0.190460,1.044537)); + hpcpush(hpxyz(-0.219683,0.178715,1.039326)); + hpcpush(hpxyz(-0.211330,0.162725,1.034959)); + hpcpush(hpxyz(-0.206261,0.134376,1.029855)); + hpcpush(hpxyz(-0.201753,0.102919,1.025328)); + hpcpush(hpxyz(-0.205795,0.072925,1.023557)); + hpcpush(hpxyz(-0.213892,0.049798,1.023831)); + hpcpush(hpxyz(-0.218429,0.022623,1.023828)); + hpcpush(hpxyz(-0.219265,0.011429,1.023820)); + hpcpush(hpxyz(-0.219265,-0.011429,1.023820)); + hpcpush(hpxyz(-0.218429,-0.022623,1.023828)); + hpcpush(hpxyz(-0.213892,-0.049798,1.023831)); + hpcpush(hpxyz(-0.205795,-0.072925,1.023557)); + hpcpush(hpxyz(-0.201753,-0.102919,1.025328)); + hpcpush(hpxyz(-0.206261,-0.134376,1.029855)); + hpcpush(hpxyz(-0.211330,-0.162725,1.034959)); + hpcpush(hpxyz(-0.219683,-0.178715,1.039326)); + hpcpush(hpxyz(-0.234056,-0.190460,1.044537)); + hpcpush(hpxyz(-0.219689,-0.185527,1.040521)); + hpcpush(hpxyz(-0.195945,-0.176675,1.034219)); + hpcpush(hpxyz(-0.178346,-0.167608,1.029514)); + hpcpush(hpxyz(-0.161208,-0.157511,1.025084)); + hpcpush(hpxyz(-0.152175,-0.151195,1.022750)); + hpcpush(hpxyz(-0.140905,-0.138269,1.019300)); + hpcpush(hpxyz(-0.128424,-0.129237,1.016462)); + hpcpush(hpxyz(-0.117272,-0.122997,1.014338)); + hpcpush(hpxyz(-0.108494,-0.122098,1.013252)); + hpcpush(hpxyz(-0.098088,-0.129874,1.013158)); + hpcpush(hpxyz(-0.084069,-0.161675,1.016468)); + hpcpush(hpxyz(-0.052858,-0.141939,1.011405)); + hpcpush(hpxyz(-0.022078,-0.163499,1.013518)); + hpcpush(hpxyz(-0.016016,-0.108729,1.006021)); + hpcpush(hpxyz(-0.016102,-0.107500,1.005890)); + hpcpush(hpxyz(-0.008219,-0.099482,1.004970)); + hpcpush(hpxyz(-0.002313,-0.097795,1.004773)); + hpcpush(hpxyz(0.009671,-0.096889,1.004729)); + hpcpush(hpxyz(0.024685,-0.088439,1.004207)); + hpcpush(hpxyz(0.035516,-0.073044,1.003293)); + hpcpush(hpxyz(0.041168,-0.053278,1.002264)); + hpcpush(hpxyz(0.039326,0.001751,1.000774)); + hpcpush(hpxyz(0.039326,-0.001751,1.000774)); + + // Pick Axe + + bshape(shPickAxe, 40); + hpcpush(hpxyz(0.064364,0.237609,1.029855)); + hpcpush(hpxyz(0.183353,-0.046466,1.017732)); + hpcpush(hpxyz(0.171819,-0.050455,1.015907)); + hpcpush(hpxyz(0.142623,-0.056105,1.011676)); + hpcpush(hpxyz(0.122591,-0.057865,1.009147)); + hpcpush(hpxyz(0.106467,-0.058329,1.007342)); + hpcpush(hpxyz(0.118180,-0.067773,1.009237)); + hpcpush(hpxyz(0.135948,-0.071025,1.011695)); + hpcpush(hpxyz(0.161536,-0.071733,1.015500)); + hpcpush(hpxyz(0.188994,-0.071278,1.020196)); + hpcpush(hpxyz(0.212623,-0.063402,1.024318)); + hpcpush(hpxyz(0.239189,-0.047822,1.029319)); + hpcpush(hpxyz(0.248564,-0.040034,1.031206)); + hpcpush(hpxyz(0.265990,-0.019250,1.034950)); + hpcpush(hpxyz(0.272276,0.000110,1.036405)); + hpcpush(hpxyz(0.269338,0.000001,1.035637)); + hpcpush(hpxyz(0.247284,-0.019782,1.030311)); + hpcpush(hpxyz(0.224346,-0.034255,1.025429)); + hpcpush(hpxyz(0.208443,-0.042147,1.022362)); + hpcpush(hpxyz(0.086124,0.253692,1.035267)); + hpcpush(hpxyz(0.064364,0.237609,1.029855)); + + bshape(shPike, 40); + hpcpush(hpxyz(0.096293,0.278465,1.042504)); + hpcpush(hpxyz(0.083339,-0.050087,1.004716)); + hpcpush(hpxyz(0.079276,-0.383984,1.074117)); + hpcpush(hpxyz(0.095192,-0.378226,1.073367)); + hpcpush(hpxyz(0.073482,-0.534658,1.136336)); + hpcpush(hpxyz(0.070202,-0.534586,1.136094)); + hpcpush(hpxyz(0.045864,-0.377144,1.069739)); + hpcpush(hpxyz(0.061795,-0.383600,1.072832)); + hpcpush(hpxyz(0.062148,-0.049623,1.003157)); + hpcpush(hpxyz(0.069133,0.279061,1.040507)); + hpcpush(hpxyz(0.096293,0.278465,1.042504)); + + bshape(shFlailBall, 40); + hpcpush(hpxyz(-0.152664,-0.216202,1.034432)); + hpcpush(hpxyz(-0.169658,-0.186257,1.031250)); + hpcpush(hpxyz(-0.175291,-0.180580,1.031182)); + hpcpush(hpxyz(-0.179213,-0.204880,1.036385)); + hpcpush(hpxyz(-0.180636,-0.179891,1.031983)); + hpcpush(hpxyz(-0.208327,-0.205555,1.041947)); + hpcpush(hpxyz(-0.195199,-0.172755,1.033415)); + hpcpush(hpxyz(-0.194159,-0.164682,1.031900)); + hpcpush(hpxyz(-0.215525,-0.177426,1.038235)); + hpcpush(hpxyz(-0.196845,-0.160074,1.031684)); + hpcpush(hpxyz(-0.233600,-0.155277,1.038595)); + hpcpush(hpxyz(-0.200041,-0.144144,1.029949)); + hpcpush(hpxyz(-0.193092,-0.139738,1.028013)); + hpcpush(hpxyz(-0.215936,-0.131441,1.031458)); + hpcpush(hpxyz(-0.191101,-0.134685,1.026966)); + hpcpush(hpxyz(-0.209451,-0.103230,1.026901)); + hpcpush(hpxyz(-0.180537,-0.121970,1.023460)); + hpcpush(hpxyz(-0.172894,-0.124532,1.022448)); + hpcpush(hpxyz(-0.180135,-0.101552,1.021157)); + hpcpush(hpxyz(-0.167729,-0.122842,1.021383)); + hpcpush(hpxyz(-0.154066,-0.088606,1.015671)); + hpcpush(hpxyz(-0.151375,-0.122930,1.018836)); + hpcpush(hpxyz(-0.148774,-0.130514,1.019396)); + hpcpush(hpxyz(-0.135083,-0.110267,1.015089)); + hpcpush(hpxyz(-0.144329,-0.133463,1.019138)); + hpcpush(hpxyz(-0.109150,-0.122417,1.013361)); + hpcpush(hpxyz(-0.134514,-0.146301,1.019558)); + hpcpush(hpxyz(-0.138895,-0.153179,1.021154)); + hpcpush(hpxyz(-0.114703,-0.151023,1.017824)); + hpcpush(hpxyz(-0.138521,-0.158550,1.021923)); + hpcpush(hpxyz(-0.108526,-0.179203,1.021710)); + hpcpush(hpxyz(-0.142650,-0.174484,1.025082)); + hpcpush(hpxyz(-0.150697,-0.175461,1.026400)); + hpcpush(hpxyz(-0.134343,-0.193130,1.027301)); + hpcpush(hpxyz(-0.154679,-0.179212,1.027639)); + hpcpush(hpxyz(-0.152664,-0.216202,1.034432)); + + bshape(shFlailTrunk, 40); + hpcpush(hpxyz(0.051293,0.275700,1.038577)); + hpcpush(hpxyz(0.057876,0.280376,1.040173)); + hpcpush(hpxyz(0.067059,0.283710,1.041628)); + hpcpush(hpxyz(0.073576,0.283978,1.042141)); + hpcpush(hpxyz(0.077320,0.279640,1.041238)); + hpcpush(hpxyz(0.147958,-0.151688,1.022204)); + hpcpush(hpxyz(0.141932,-0.161853,1.022908)); + hpcpush(hpxyz(0.138281,-0.166934,1.023224)); + hpcpush(hpxyz(0.129252,-0.166536,1.021979)); + hpcpush(hpxyz(0.118813,-0.160892,1.019805)); + hpcpush(hpxyz(0.112195,-0.152881,1.017821)); + hpcpush(hpxyz(0.051293,0.275700,1.038577)); + + // group 2 layer 7 + + bshape(shFlailChain, 38); + hpcpush(hpxyz(0.124731,-0.149526,1.018781)); + hpcpush(hpxyz(0.117490,-0.160203,1.019543)); + hpcpush(hpxyz(0.106751,-0.149132,1.016679)); + hpcpush(hpxyz(0.095911,-0.162180,1.017596)); + hpcpush(hpxyz(0.085170,-0.151131,1.014936)); + hpcpush(hpxyz(0.074321,-0.161824,1.015732)); + hpcpush(hpxyz(0.062353,-0.149567,1.013044)); + hpcpush(hpxyz(0.052646,-0.162759,1.014526)); + hpcpush(hpxyz(0.041822,-0.150522,1.012129)); + hpcpush(hpxyz(0.032058,-0.161359,1.013442)); + hpcpush(hpxyz(0.023596,-0.147919,1.011156)); + hpcpush(hpxyz(0.013752,-0.158813,1.012626)); + hpcpush(hpxyz(0.005196,-0.149008,1.011054)); + hpcpush(hpxyz(-0.004760,-0.161206,1.012922)); + hpcpush(hpxyz(-0.014646,-0.148927,1.011135)); + hpcpush(hpxyz(-0.027247,-0.159995,1.013085)); + hpcpush(hpxyz(-0.039846,-0.148910,1.011811)); + hpcpush(hpxyz(-0.052728,-0.162603,1.014505)); + hpcpush(hpxyz(-0.066903,-0.150243,1.013434)); + hpcpush(hpxyz(-0.077482,-0.162849,1.016131)); + hpcpush(hpxyz(-0.093362,-0.150445,1.015554)); + hpcpush(hpxyz(-0.104284,-0.165774,1.018998)); + hpcpush(hpxyz(-0.117892,-0.153274,1.018524)); + hpcpush(hpxyz(-0.131957,-0.166335,1.022292)); + hpcpush(hpxyz(-0.144633,-0.153714,1.022031)); + hpcpush(hpxyz(-0.156334,-0.168243,1.026034)); + hpcpush(hpxyz(-0.173918,-0.153010,1.026479)); + hpcpush(hpxyz(-0.173894,-0.147770,1.025707)); + hpcpush(hpxyz(-0.156165,-0.131894,1.020678)); + hpcpush(hpxyz(-0.144597,-0.145973,1.020890)); + hpcpush(hpxyz(-0.131802,-0.132992,1.017378)); + hpcpush(hpxyz(-0.117856,-0.145631,1.017398)); + hpcpush(hpxyz(-0.104131,-0.132849,1.014146)); + hpcpush(hpxyz(-0.093350,-0.147924,1.015183)); + hpcpush(hpxyz(-0.077354,-0.135296,1.012071)); + hpcpush(hpxyz(-0.066892,-0.147748,1.013067)); + hpcpush(hpxyz(-0.052601,-0.135298,1.010481)); + hpcpush(hpxyz(-0.039846,-0.148910,1.011811)); + hpcpush(hpxyz(-0.027144,-0.137836,1.009820)); + hpcpush(hpxyz(-0.014646,-0.148927,1.011135)); + hpcpush(hpxyz(-0.004647,-0.136736,1.009316)); + hpcpush(hpxyz(0.005196,-0.149008,1.011054)); + hpcpush(hpxyz(0.013843,-0.139323,1.009754)); + hpcpush(hpxyz(0.023585,-0.150350,1.011514)); + hpcpush(hpxyz(0.032171,-0.137084,1.009865)); + hpcpush(hpxyz(0.041833,-0.148099,1.011772)); + hpcpush(hpxyz(0.052770,-0.136144,1.010604)); + hpcpush(hpxyz(0.062353,-0.149567,1.013044)); + hpcpush(hpxyz(0.074434,-0.137691,1.012175)); + hpcpush(hpxyz(0.085181,-0.148721,1.014581)); + hpcpush(hpxyz(0.096024,-0.138086,1.014046)); + hpcpush(hpxyz(0.106739,-0.151540,1.017034)); + hpcpush(hpxyz(0.117580,-0.140943,1.016705)); + hpcpush(hpxyz(0.124720,-0.151933,1.019136)); + hpcpush(hpxyz(0.124731,-0.149526,1.018781)); + + + bshape(shBigHepta, 11); + for(int t=0; t<=7; t++) hpcpush(ddi(t*12, -hexf*1.5) * C0); + + bshape(shBigTriangle, 11); + for(int t=0; t<=3; t++) hpcpush(ddi(t*28, -hexf*1.5) * C0); + + bshapeend(); + + for(int i=0; i<8; i++) + shUser[i][0].prio = 1 + i, + shUser[i][1].prio = 1 + i, + shUser[i][2].prio = 50 + i; + + prehpc = qhpc; + } + +struct drawshape { + vector list; + bool sym; + int rots; + hyperpoint shift, spin; + }; + +drawshape dsUser[8][3], *dsCur; + +int dslayer; +bool floordraw; + +void pushShape(const drawshape& ds) { + + transmatrix T = rgpushxto0(ds.shift) * rspintox(ds.spin); + + for(int r=0; r=0; i--) + hpcpush(T * spin(2*M_PI*r/ds.rots) * mirrortrans * ds.list[i]); + } + } + hpcpush(T * ds.list[0]); + } + +void saveImages() { + qhpc = prehpc; + + for(int i=0; i<8; i++) for(int j=0; j<3; j++) { + if(size(dsUser[i][j].list)) { + shUser[i][j].s = qhpc; + first = true; + pushShape(dsUser[i][j]); + shUser[i][j].e = qhpc; + } + else shUser[i][j].s = 0; + } + } + +int poly_outline; + +void queuepoly(const transmatrix& V, int ct, const hpcshape& h, int col) { + /* printf("draw poly #%d-%d at:\n", h.s, h.e); + display(V); */ + polytodraw ptd; + ptd.V = V; + ptd.start = h.s, ptd.end = h.e; + ptd.col = (darkened(col >> 8) << 8) + (col & 0xFF); + ptd.prio = h.prio; + ptd.outline = poly_outline; + ptds.push_back(ptd); + } + diff --git a/steamvisualinterface.cpp b/steamvisualinterface.cpp new file mode 100644 index 00000000..6deea01f --- /dev/null +++ b/steamvisualinterface.cpp @@ -0,0 +1,54 @@ +// PRIVATE + +#include "sdk/public/steam/steam_api.h" +#include "steamvisualinterface.h" + +class SteamContact { + public: + + STEAM_CALLBACK( SteamContact, OnUserStatsReceived, UserStatsReceived_t, m_CallbackStatsReceived ); + SteamContact (); + + void OnFindLeaderboard( LeaderboardFindResult_t *pFindLearderboardResult, bool bIOFailure ); + void OnDownloadScores( LeaderboardScoresDownloaded_t *pLeaderboardScoresDownloaded, bool bIOFailure ); + CCallResult m_SteamCallResultCreateLeaderboard; + CCallResult m_SteamCallResultScoresDownloaded; + }; + +SteamContact :: SteamContact() +: m_CallbackStatsReceived(this, &SteamContact::OnUserStatsReceived) + { } + +static SteamContact *steam; + +callback_statsreceived sr; +callback_findleaderboard fl; +callback_scoresdownload sdl; + +void init_steamvisualinterface(callback_statsreceived _sr, callback_findleaderboard _fl, callback_scoresdownload _sdl) { + sr = _sr; + fl = _fl; + sdl = _sdl; + steam = new SteamContact; + } + +void register_callback(SteamAPICall_t handle) { + steam->m_SteamCallResultCreateLeaderboard.Set( handle, steam, &SteamContact::OnFindLeaderboard ); + } + +void register_callback_download(SteamAPICall_t handle) { + steam->m_SteamCallResultScoresDownloaded.Set( handle, steam, &SteamContact::OnDownloadScores ); + } + +void SteamContact::OnFindLeaderboard( LeaderboardFindResult_t *pFindLeaderboardResult, bool bIOFailure ) { + fl(pFindLeaderboardResult, bIOFailure); + } + +void SteamContact::OnDownloadScores( LeaderboardScoresDownloaded_t *pLeaderboardScoresDownloaded, bool bIOFailure ) { + sdl(pLeaderboardScoresDownloaded, bIOFailure); + } + +void SteamContact::OnUserStatsReceived( UserStatsReceived_t *pCallback ) { + sr(pCallback); + } + diff --git a/zeno.css b/zeno.css new file mode 100644 index 00000000..2820451a --- /dev/null +++ b/zeno.css @@ -0,0 +1,26 @@ +BODY { + background: #000000; color: #C0C0C0 +} +A { + font-weight: bold; color: #FFFF00; text-decoration: none +} +A:hover { + font-weight: bold; color: #FF0000; text-decoration: underline +} +h1 { + color: #FF0000 +} +h2 { + color: #FF8000 +} +.pic { + vertical-align: top; width: 100; text-align: center +} +img { + border-style:outset; border-color: white; border-width:2px; +} +.noborder { + border-width:0px; +} +td { + padding-top:8px;