mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 13:07:16 +00:00
10.0g
This commit is contained in:
parent
4f2af2f2c4
commit
130fefa4c4
@ -536,7 +536,7 @@ void achievement_final(bool really_final) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(sphere && euclidland == laHalloween) {
|
||||
if(sphere && specialland == laHalloween) {
|
||||
if(shmup::on || chaosmode || purehepta || numplayers() > 1 || tactic::on || randomPatternsMode)
|
||||
return;
|
||||
achievement_score(LB_HALLOWEEN, items[itTreat]);
|
||||
|
@ -967,7 +967,7 @@ void setvideomode() {
|
||||
|
||||
if(vid.antialias & AA_MULTI) {
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (vid.antialias & AA_MULTI16) ? 16 : 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1773,3 +1773,61 @@
|
||||
- peaceful mode state is now displayed correctly in the main menu
|
||||
- readded the sound when breaking mirrors
|
||||
- fixed the vertical position of the flower in hand
|
||||
|
||||
2017.07.24 01:49 version 10.0d
|
||||
- the bottom line in the inventory mode is now always visible (i.e. you can exit the inventory with mouse)
|
||||
- peaceful mode and shmup mode are now compatible
|
||||
- fixed the problems with free Orbs of Safety in the Orb Strategy mode
|
||||
- fixed some texts
|
||||
|
||||
2017.07.25 03:21 version 10.0e
|
||||
- more fixes for the peaceful mode: tortoises no longer move in shmup; Fire Cultists
|
||||
no longer throw fire; Ivy no longer grows; no more statues under Ivy; no more
|
||||
Grimoires; the Knights no longer talk about war; the Princess no longer wants
|
||||
revenge; the Sword is graphically replaced with a shovel and digs again
|
||||
- fixed a bug with loading the old style config (affected the mobile versions)
|
||||
- fixed the arrow keys to scroll
|
||||
- the Android version should no longer draw the screen while locked
|
||||
- victory speedrun leaderboards in orb strategy
|
||||
- Narcissist and Mirror Spirit kills count
|
||||
|
||||
2017.07.25 21:24 version 10.0f
|
||||
- color saving on 32bit machines should be fixed
|
||||
- 'save config' appears again in the basic config
|
||||
|
||||
2017.08.06 14:00 version 10.0g
|
||||
- added a new Yendor Challenge
|
||||
- improved the efficiency in the Hall of Mirrors
|
||||
- reduced the sulphur lakes in the Heptagonal Hell
|
||||
- new princess messages
|
||||
- Halloween and Reflection should no longer appear in the Chaos Yendor Challenge
|
||||
- OoY now automatically activates if you move the boat into it
|
||||
- no more 'you have found ...' spam while moving an object with a boat
|
||||
- checkmate rule no longer thinks you are protected when standing on top of OoY
|
||||
- fixed bugs with (hardcore) turn-based multiplayer
|
||||
- bugfix: Dragon Chasm->Reptiles did not respect the Elixir of Life requirement
|
||||
- no longer crash on saving peacemode
|
||||
- map/vector editor commands now always fit on the screen
|
||||
- [ui] translations updated, languages selectable from a menu
|
||||
- [ui] new start menu
|
||||
- [ui] the X for Yendor/Compass is now placed perfectly (well, on the same pixel, and not in Euclidean) and has an aura effect
|
||||
- [ui] mouse now acts on click, not on release (configurable in the menu)
|
||||
- [ui] animate legs in char select
|
||||
- [ui] subtle animations in the inventory/kill list when a monster is killed
|
||||
- [ui] player death animations in the hardcore mode
|
||||
- [osm] fixed a bug with mirroring message
|
||||
- [osm] fixed a bug with Dead Orbs gained incorrectly
|
||||
- [osm] rewards for extra Daisies and Elemental Gems
|
||||
- [osm] messages after 25 PF, DDaisies
|
||||
- [osm] the inventory screen now displays more information
|
||||
- [osm] dead orbs no longer require Graveyard in the OSM -- more logical that way
|
||||
- [osm] command line options added for OSM and peace
|
||||
- [osm] improve centering the orb display
|
||||
- [cheat] new cheats: save princess, unlock all touched Orbs of Yendor
|
||||
- [cheat] 'F' clears the "killed by spilling slime carelessly" status
|
||||
- [cheat] removed cheats that are made redundant by the Map Editor
|
||||
- [cheat] a special screen for debugging the land generation (cheat: shift+G)
|
||||
- [mobile] remove menu 'button' from mobiles
|
||||
- [mobile] the Tutorial is somewhat adjusted for mobiles
|
||||
- [mobile] map/vector editor available (though not very convenient)
|
||||
|
||||
|
81
complex.cpp
81
complex.cpp
@ -670,7 +670,7 @@ namespace princess {
|
||||
|
||||
playSound(c, princessgender() ? "speak-princess" : "speak-prince");
|
||||
retry:
|
||||
if(msgid >= 32) msgid = 0;
|
||||
if(msgid >= 127) msgid = 0;
|
||||
|
||||
bool inpalace = c->land == laPalace || c->land == laDungeon;
|
||||
|
||||
@ -692,15 +692,36 @@ namespace princess {
|
||||
else if(msgid == 4 && !inpalace && m == moPrincess && !peace::on) {
|
||||
addMessage(XLAT("\"I have been trained to fight with a Hypersian scimitar, you know?\"", m));
|
||||
}
|
||||
else if(msgid == 5 && !inpalace) {
|
||||
else if(msgid == 16 && !inpalace) {
|
||||
addMessage(XLAT("\"I would love to come to your world with you!\"", m));
|
||||
}
|
||||
else if(msgid == 6 && !inpalace) {
|
||||
else if(msgid == 20 && !inpalace) {
|
||||
addMessage(XLAT("\"I do not like butterflies. They are treacherous.\"", m));
|
||||
}
|
||||
else if(msgid == 32 && !inpalace) {
|
||||
addMessage(XLAT("\"Straight lines stay close to each other forever, this is so romantic!\"", m));
|
||||
}
|
||||
else if(msgid == 7 && !inpalace) {
|
||||
else if(msgid == 40 && !inpalace) {
|
||||
addMessage(XLAT("\"I hate roses.\"", m));
|
||||
}
|
||||
else if(msgid == 48 && !inpalace) {
|
||||
addMessage(XLAT("\"Maps... Just like the world, but smaller... how is that even possible?!\"", m));
|
||||
}
|
||||
else if(msgid == 64) {
|
||||
addMessage(XLAT("\"In this world there is plenty of space for everyone. We do not need wars.\"", m));
|
||||
}
|
||||
else if(msgid == 65) {
|
||||
addMessage(XLAT("\"Only the stupid hyperbugs do not understand this.\"", m));
|
||||
}
|
||||
else if(msgid == 72 && !inpalace) {
|
||||
addMessage(XLAT("\"I have once talked to a Yendorian researcher... he was only interested in infinite trees.\"", m));
|
||||
}
|
||||
else if(msgid == 73 && !inpalace) {
|
||||
addMessage(XLAT("\"Infinite trees are boring. I prefer other graphs.\"", m));
|
||||
}
|
||||
else if(msgid == 80) {
|
||||
addMessage(XLAT("\"Are there Temples of Cthulhu in your world? Why not?\"", m));
|
||||
}
|
||||
else {
|
||||
msgid++; goto retry;
|
||||
}
|
||||
@ -1126,6 +1147,7 @@ namespace mirror {
|
||||
}
|
||||
|
||||
void createHere(cellwalker cw, int cpid) {
|
||||
if(!cw.c) return;
|
||||
if(cw.c->wall == waCloud)
|
||||
createMirages(cw, cpid);
|
||||
if(cw.c->wall == waMirror)
|
||||
@ -1133,6 +1155,7 @@ namespace mirror {
|
||||
}
|
||||
|
||||
void breakMirror(cellwalker cw, int pid) {
|
||||
if(!cw.c) return;
|
||||
cell *c = cw.c;
|
||||
if(c->wall == waMirror || c->wall == waCloud) {
|
||||
drawParticles(c, winf[c->wall].color, 16);
|
||||
@ -1255,8 +1278,11 @@ namespace mirror {
|
||||
}
|
||||
return make_pair(goout, cw);
|
||||
}
|
||||
|
||||
int depth(cell *c) { return c->landparam & 255; }
|
||||
|
||||
cellwalker reflect(cellwalker cw, bool debug) {
|
||||
cellwalker reflect0(cell *c) {
|
||||
cellwalker cw(c, 0, false);
|
||||
int stepcount = 0;
|
||||
cellwalker cwcopy = cw;
|
||||
static vector<int> v;
|
||||
@ -1264,18 +1290,15 @@ namespace mirror {
|
||||
while(true) {
|
||||
if(!inmirror(cw)) break;
|
||||
stepcount++; if(stepcount > 10000) {
|
||||
if(debug) cw.c->wall = waBoat;
|
||||
if(debug) printf("fail\n");
|
||||
return cw;
|
||||
}
|
||||
cell *c0 = cwpeek(cw, 0);
|
||||
int go = 0;
|
||||
if(!inmirror(c0)) go = 2;
|
||||
else if(c0->landparam && c0->landparam < cw.c->landparam) go = 1;
|
||||
else if(depth(c0) && depth(c0) < depth(cw.c)) go = 1;
|
||||
if(go) {
|
||||
v.push_back(0);
|
||||
cwstep(cw);
|
||||
if(debug) queuemarkerat(gmatrix[cw.c], 0x00FF0020);
|
||||
if(go == 2) break;
|
||||
}
|
||||
else {
|
||||
@ -1299,7 +1322,6 @@ namespace mirror {
|
||||
cwspin(cw, 2);
|
||||
v.push_back(2);
|
||||
cwstep(cw);
|
||||
if(debug) queuemarkerat(gmatrix[cw.c], 0xC9C90080);
|
||||
v.push_back(0);
|
||||
cwspin(cw, 3);
|
||||
v.push_back(3);
|
||||
@ -1342,19 +1364,33 @@ namespace mirror {
|
||||
return cw;
|
||||
}
|
||||
|
||||
#if ISMOBILE==0
|
||||
void debug() {
|
||||
if(!mouseover) return;
|
||||
queuemarkerat(gmatrix[mouseover], 0xFF0000FF);
|
||||
#if CAP_SDL
|
||||
cellwalker mw(mouseover, (SDL_GetTicks()/1000) % mouseover->type, (SDL_GetTicks()/500) % 2);
|
||||
#else
|
||||
cellwalker mw(mouseover, 0, 0);
|
||||
#endif
|
||||
mw = mirror::reflect(mw, true);
|
||||
queuemarkerat(gmatrix[mw.c], 0x800000FF);
|
||||
static const int CACHESIZE = 1<<12; // must be a power of 2
|
||||
static const int CACHEMASK = CACHESIZE-1;
|
||||
|
||||
pair<cell*, cellwalker> cache[CACHESIZE];
|
||||
int nextcache;
|
||||
|
||||
void clearcache() {
|
||||
for(int i=0; i<CACHESIZE; i++) cache[i].first = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
cellwalker reflect(const cellwalker& cw) {
|
||||
if(!cw.c) return cw;
|
||||
int cid = (cw.c->landparam >> 8) & CACHEMASK;
|
||||
if(cache[cid].first != cw.c) {
|
||||
cid = nextcache++;
|
||||
nextcache &= CACHEMASK;
|
||||
cw.c->landparam &= ~ (CACHEMASK << 8);
|
||||
cw.c->landparam |= (nextcache << 8);
|
||||
cache[cid].first = cw.c;
|
||||
cache[cid].second = reflect0(cw.c);
|
||||
}
|
||||
cellwalker res = cache[cid].second;
|
||||
cwspin(res, cw.spin);
|
||||
if(cw.mirrored) res.mirrored = !res.mirrored;
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace hive {
|
||||
@ -2938,5 +2974,6 @@ auto ccm = addHook(clearmemory, 0, [] () {
|
||||
prairie::enter = NULL;
|
||||
prairie::tchoices.clear();
|
||||
prairie::beaststogen.clear();
|
||||
mirror::clearcache();
|
||||
});
|
||||
|
||||
|
147
config.cpp
147
config.cpp
@ -1,8 +1,14 @@
|
||||
videopar vid;
|
||||
|
||||
charstyle& getcs() {
|
||||
if(multi::players>1 && multi::cpid >= 0 && multi::cpid < multi::players)
|
||||
return multi::scs[multi::cpid];
|
||||
#if ISANDROID
|
||||
#define ANDROID_SETTINGS settingsChanged = true;
|
||||
#else
|
||||
#define ANDROID_SETTINGS ;
|
||||
#endif
|
||||
|
||||
charstyle& getcs(int id) {
|
||||
if(multi::players>1 && id >= 0 && id < multi::players)
|
||||
return multi::scs[id];
|
||||
else
|
||||
return vid.cs;
|
||||
}
|
||||
@ -114,7 +120,7 @@ template<> struct saver<bool> : dsaver<bool> {
|
||||
template<> struct saver<unsigned> : dsaver<unsigned> {
|
||||
saver<unsigned>(unsigned& val) : dsaver<unsigned>(val) { }
|
||||
string save() { return itsh(val); }
|
||||
void load(const string& s) { val = strtol(s.c_str(), NULL, 16); }
|
||||
void load(const string& s) { val = (unsigned) strtoll(s.c_str(), NULL, 16); }
|
||||
};
|
||||
|
||||
template<> struct saver<ld> : dsaver<ld> {
|
||||
@ -272,20 +278,27 @@ void initConfig() {
|
||||
|
||||
vid.killreduction = 0;
|
||||
|
||||
addsaver(vid.skipstart, "skip the start menu", false);
|
||||
addsaver(vid.quickmouse, "quick mouse", !ISPANDORA);
|
||||
|
||||
// colors
|
||||
|
||||
addsaver(backcolor, "color:background");
|
||||
addsaver(forecolor, "color:foreground");
|
||||
addsaver(bordcolor, "color:borders");
|
||||
|
||||
// modes
|
||||
|
||||
addsaverenum(geometry, "mode-geometry");
|
||||
addsaverenum(euclidland, "mode-geometry land");
|
||||
addsaver(shmup::on, "mode-shmup", false);
|
||||
addsaver(hardcore, "mode-hardcore", false);
|
||||
addsaver(chaosmode, "mode-chaos");
|
||||
addsaver(inv::on, "mode-Orb Strategy");
|
||||
addsaver(purehepta, "mode-heptagonal", false);
|
||||
addsaver(peace::on, "mode-peace");
|
||||
addsaver(peace::otherpuzzles, "mode-peace-submode");
|
||||
addsaverenum(specialland, "land for special modes");
|
||||
|
||||
addsaver(backcolor, "color:background");
|
||||
addsaver(forecolor, "color:foreground");
|
||||
addsaver(bordcolor, "color:borders");
|
||||
addsaver(viewdists, "expansion mode");
|
||||
|
||||
shmup::initConfig();
|
||||
@ -378,9 +391,9 @@ void loadOldConfig(FILE *f) {
|
||||
err=fscanf(f, "%d%d", &aa, &bb);
|
||||
vid.darkhepta = aa; vid.shifttarget = bb;
|
||||
|
||||
aa = geometry; bb = euclidland; cc = shmup::on; dd = hardcore;
|
||||
aa = geometry; bb = specialland; cc = shmup::on; dd = hardcore;
|
||||
err=fscanf(f, "%d%d%d%d", &aa, &bb, &cc, &dd);
|
||||
geometry = eGeometry(aa); euclidland = eLand(bb); shmup::on = cc; hardcore = dd;
|
||||
geometry = eGeometry(aa); specialland = eLand(bb); shmup::on = cc; hardcore = dd;
|
||||
|
||||
shmup::loadConfig(f);
|
||||
|
||||
@ -526,7 +539,7 @@ void handleAllConfig(int sym, int uni) {
|
||||
|
||||
void showGraphConfig() {
|
||||
gamescreen(0);
|
||||
cmode = sm::SIDE;
|
||||
cmode = vid.xres > vid.yres * 1.4 ? sm::SIDE : 0;
|
||||
|
||||
dialog::init(XLAT("graphics configuration"));
|
||||
|
||||
@ -683,7 +696,7 @@ void switchFullscreen() {
|
||||
vid.full = !vid.full;
|
||||
#if ISANDROID
|
||||
addMessage(XLAT("Reenter HyperRogue to apply this setting"));
|
||||
settingsChanged = true;
|
||||
ANDROID_SETTINGS
|
||||
#endif
|
||||
#if CAP_SDL
|
||||
if(true) {
|
||||
@ -700,9 +713,8 @@ void switchGL() {
|
||||
vid.usingGL = !vid.usingGL;
|
||||
if(vid.usingGL) addMessage(XLAT("openGL mode enabled"));
|
||||
if(!vid.usingGL) addMessage(XLAT("openGL mode disabled"));
|
||||
#if ISANDROID
|
||||
settingsChanged = true;
|
||||
#elif CAP_SDL
|
||||
ANDROID_SETTINGS;
|
||||
#if CAP_SDL
|
||||
setvideomode();
|
||||
#endif
|
||||
}
|
||||
@ -742,24 +754,17 @@ void showBasicConfig() {
|
||||
dialog::addBoolItem(XLAT("send scores to Steam leaderboards"), (vid.steamscore&1), 'l');
|
||||
#endif
|
||||
|
||||
dialog::addBoolItem(XLAT("skip the start menu"), vid.skipstart, 'm');
|
||||
#if !ISMOBILE
|
||||
dialog::addBoolItem(XLAT("quick mouse"), vid.quickmouse, 'M');
|
||||
#endif
|
||||
|
||||
if(CAP_SHMUP && !ISMOBILE)
|
||||
dialog::addSelItem(XLAT("configure keys/joysticks"), "", 'p');
|
||||
|
||||
dialog::addItem(XLAT("reset all configuration"), 'R');
|
||||
showAllConfig();
|
||||
|
||||
if(lang() != 0) {
|
||||
string tw = "";
|
||||
string s = XLAT("TRANSLATIONWARNING");
|
||||
if(s != "" && s != "TRANSLATIONWARNING") tw += s;
|
||||
s = XLAT("TRANSLATIONWARNING2");
|
||||
if(s != "" && s != "TRANSLATIONWARNING2") { if(tw != "") tw += " "; tw += s; }
|
||||
if(tw != "") {
|
||||
dialog::addBreak(50);
|
||||
dialog::addHelp(tw);
|
||||
dialog::lastItem().color = 0xFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
dialog::display();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
@ -768,6 +773,9 @@ void showBasicConfig() {
|
||||
char xuni = uni | 96;
|
||||
|
||||
if(uni >= 32 && uni < 64) xuni = uni;
|
||||
|
||||
if(uni == 'M') vid.quickmouse = !vid.quickmouse;
|
||||
else if(xuni == 'm') vid.skipstart = !vid.skipstart;
|
||||
|
||||
if(xuni == 'c') { vid.axes += 60 + (shiftmul > 0 ? 1 : -1); vid.axes %= 5; }
|
||||
|
||||
@ -778,14 +786,8 @@ void showBasicConfig() {
|
||||
dialog::editNumber(effvolume, 0, 128, 10, 60, XLAT("sound effects volume"), "");
|
||||
}
|
||||
|
||||
if(CAP_TRANS && xuni == 'l') {
|
||||
vid.language += (shiftmul>0?1:-1);
|
||||
vid.language %= NUMLAN;
|
||||
if(vid.language < 0) vid.language += NUMLAN;
|
||||
#if ISANDROID
|
||||
settingsChanged = true;
|
||||
#endif
|
||||
}
|
||||
if(CAP_TRANS && xuni == 'l')
|
||||
pushScreen(selectLanguageScreen);
|
||||
|
||||
if(xuni == 'g') pushScreen(showCustomizeChar);
|
||||
|
||||
@ -1059,7 +1061,14 @@ void switchcolor(unsigned int& c, unsigned int* cs) {
|
||||
dialog::openColorDialog(c, cs);
|
||||
}
|
||||
|
||||
double cc_footphase;
|
||||
int lmousex, lmousey;
|
||||
|
||||
void showCustomizeChar() {
|
||||
|
||||
cc_footphase += hypot(mousex - lmousex, mousey - lmousey);
|
||||
lmousex = mousex; lmousey = mousey;
|
||||
|
||||
gamescreen(4);
|
||||
dialog::init(XLAT("Customize character"));
|
||||
|
||||
@ -1087,12 +1096,13 @@ void showCustomizeChar() {
|
||||
dialog::display();
|
||||
|
||||
int firsty = dialog::items[0].position / 2;
|
||||
int scale = firsty - 2 * vid.fsize;
|
||||
|
||||
initquickqueue();
|
||||
transmatrix V = atscreenpos(vid.xres/2, firsty, firsty - 2 * vid.fsize);
|
||||
transmatrix V = atscreenpos(vid.xres/2, firsty, scale);
|
||||
|
||||
double alpha = atan2(mousex - vid.xres/2, mousey - firsty) - M_PI/2;
|
||||
drawMonsterType(moPlayer, NULL, V * spin(alpha), 0, 0);
|
||||
drawMonsterType(moPlayer, NULL, V * spin(alpha), 0, cc_footphase / scale);
|
||||
quickqueue();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
@ -1104,7 +1114,7 @@ void showCustomizeChar() {
|
||||
if(xuni == 'a') { shmup::cpid_edit++; shmup::cpid_edit %= 60; }
|
||||
if(xuni == 'g') {
|
||||
cs.charid++;
|
||||
if(cs.charid == 2 && !princess::everSaved) cs.charid = 4;
|
||||
if(cs.charid == 2 && !princess::everSaved && !autocheat) cs.charid = 4;
|
||||
cs.charid %= 10;
|
||||
}
|
||||
if(xuni == 'p') vid.samegender = !vid.samegender;
|
||||
@ -1148,3 +1158,62 @@ void resetConfigMenu() {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
void selectLanguageScreen() {
|
||||
gamescreen(4);
|
||||
dialog::init("select language"); // intentionally not translated
|
||||
|
||||
int v = vid.language;
|
||||
dynamicval<int> d(vid.language, -1);
|
||||
|
||||
for(int i=0; i<NUMLAN-1 || i == v; i++) {
|
||||
vid.language = i;
|
||||
dialog::addSelItem(XLAT("EN"), its(100 * transcompleteness[i] / transcompleteness[0]) + "%", 'a'+i);
|
||||
}
|
||||
|
||||
dialog::addBreak(50);
|
||||
vid.language = -1;
|
||||
dialog::addBoolItem(XLAT("default") + ": " + XLAT("EN"), v == -1, '0');
|
||||
dialog::addItem(XLAT("exit configuration"), '1');
|
||||
|
||||
dialog::addBreak(50);
|
||||
|
||||
vid.language = v;
|
||||
if(lang() >= 1)
|
||||
dialog::addHelp(XLAT("add credits for your translation here"));
|
||||
else
|
||||
dialog::addHelp(XLAT("original language"));
|
||||
|
||||
if(lang() != 0) {
|
||||
string tw = "";
|
||||
string s = XLAT("TRANSLATIONWARNING");
|
||||
if(s != "" && s != "TRANSLATIONWARNING") tw += s;
|
||||
s = XLAT("TRANSLATIONWARNING2");
|
||||
if(s != "" && s != "TRANSLATIONWARNING2") { if(tw != "") tw += " "; tw += s; }
|
||||
if(tw != "") {
|
||||
dialog::addHelp(tw);
|
||||
dialog::lastItem().color = 0xFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
dialog::display();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
|
||||
char xuni = uni | 96;
|
||||
if(uni == '0') {
|
||||
vid.language = -1;
|
||||
ANDROID_SETTINGS;
|
||||
}
|
||||
|
||||
else if(xuni >= 'a' && xuni < 'a'+NUMLAN) {
|
||||
vid.language = xuni - 'a';
|
||||
ANDROID_SETTINGS;
|
||||
}
|
||||
|
||||
else if(doexiton(sym, uni))
|
||||
popScreen();
|
||||
};
|
||||
}
|
||||
|
51
control.cpp
51
control.cpp
@ -606,40 +606,45 @@ void mainloopiter() {
|
||||
bool rollchange = (cmode & sm::OVERVIEW) && getcstat >= 2000 && cheater;
|
||||
|
||||
if(ev.type == SDL_MOUSEBUTTONDOWN) {
|
||||
flashMessages();
|
||||
mousepressed = true;
|
||||
mousepressed = ev.type == SDL_MOUSEBUTTONDOWN;
|
||||
if(mousepressed) flashMessages();
|
||||
mousing = true;
|
||||
actonrelease = true;
|
||||
|
||||
if(ev.button.button==SDL_BUTTON_WHEELDOWN) {
|
||||
sym = uni = PSEUDOKEY_WHEELDOWN;
|
||||
bool act = false;
|
||||
|
||||
if(vid.quickmouse) {
|
||||
act = ev.type == SDL_MOUSEBUTTONDOWN;
|
||||
}
|
||||
if(ev.button.button==SDL_BUTTON_WHEELUP) {
|
||||
sym = uni = PSEUDOKEY_WHEELUP;
|
||||
else {
|
||||
act = actonrelease && ev.type == SDL_MOUSEBUTTONUP;
|
||||
actonrelease = ev.type == SDL_MOUSEBUTTONDOWN;
|
||||
}
|
||||
else if(ev.button.button == SDL_BUTTON_RIGHT) {
|
||||
sym = 1; didsomething = true;
|
||||
}
|
||||
else if(ev.button.button == SDL_BUTTON_MIDDLE) {
|
||||
sym = 2; didsomething = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!act) ;
|
||||
|
||||
if(ev.type == SDL_MOUSEBUTTONUP) {
|
||||
mousepressed = false;
|
||||
mousing = true;
|
||||
if(ev.button.button==SDL_BUTTON_RIGHT || leftclick)
|
||||
else if(ev.button.button==SDL_BUTTON_RIGHT || leftclick)
|
||||
sym = SDLK_F1;
|
||||
else if(ev.button.button==SDL_BUTTON_MIDDLE || rightclick)
|
||||
sym = 1, didsomething = true;
|
||||
else if(ev.button.button == SDL_BUTTON_LEFT && actonrelease) {
|
||||
else if(ev.button.button == SDL_BUTTON_LEFT) {
|
||||
sym = getcstat, uni = getcstat, shiftmul = getcshift;
|
||||
}
|
||||
else if(ev.button.button == SDL_BUTTON_WHEELUP && rollchange) {
|
||||
sym = getcstat, uni = getcstat, shiftmul = getcshift, wheelclick = true;
|
||||
|
||||
else if(ev.button.button==SDL_BUTTON_WHEELDOWN) {
|
||||
if(rollchange) {
|
||||
sym = getcstat, uni = getcstat, shiftmul = getcshift, wheelclick = true;
|
||||
}
|
||||
else {
|
||||
sym = uni = PSEUDOKEY_WHEELDOWN;
|
||||
}
|
||||
}
|
||||
else if(ev.button.button == SDL_BUTTON_WHEELDOWN && rollchange) {
|
||||
sym = getcstat, uni = getcstat, shiftmul = -getcshift, wheelclick = true;
|
||||
if(ev.button.button==SDL_BUTTON_WHEELUP) {
|
||||
if(rollchange) {
|
||||
sym = getcstat, uni = getcstat, shiftmul = -getcshift, wheelclick = true;
|
||||
}
|
||||
else {
|
||||
sym = uni = PSEUDOKEY_WHEELUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
394
debug.cpp
Normal file
394
debug.cpp
Normal file
@ -0,0 +1,394 @@
|
||||
static int orbid = 0;
|
||||
|
||||
void debugScreen();
|
||||
|
||||
eItem nextOrb() {
|
||||
orbid++;
|
||||
eItem i = eItem(orbid % ittypes);
|
||||
if(itemclass(i) == IC_ORB) return i;
|
||||
else return nextOrb();
|
||||
}
|
||||
|
||||
eItem randomTreasure() {
|
||||
eItem i = eItem(hrand(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; a<ittypes; a++) {
|
||||
eItem i = eItem(a);
|
||||
if(itemclass(i) != IC_TREASURE) continue;
|
||||
int q = 2*items[i];
|
||||
if(a == lt) q -= (2*cv-1);
|
||||
if(a == itEmerald && bearsCamelot(cwt.c->land)) q -= 8;
|
||||
if(a == itElixir && isCrossroads(cwt.c->land)) q -= 7;
|
||||
if(a == itIvory && isCrossroads(cwt.c->land)) q -= 6;
|
||||
if(a == itPalace && isCrossroads(cwt.c->land)) q -= 5;
|
||||
if(a == itIvory && cwt.c->land == laJungle) q -= 5;
|
||||
if(a == itIvory && cwt.c->land == laPalace) q -= 5;
|
||||
if(q < bq) bq = q, cq = 0;
|
||||
if(q == bq) { cq++; if(hrand(cq) == 0) best = i; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
bool isTechnicalLand(eLand l) {
|
||||
return l == laNone || l == laOceanWall || l == laBarrier || l == laCanvas ||
|
||||
l == laHauntedWall || l == laHauntedBorder || l == laCA ||
|
||||
l == laMirrorWall || l == laMirrored || l == laMirrored2;
|
||||
}
|
||||
|
||||
eLand cheatdest;
|
||||
|
||||
void cheatMoveTo(eLand l) {
|
||||
cheatdest = l;
|
||||
if(l == laCrossroads5) l = laCrossroads;
|
||||
activateSafety(l);
|
||||
cheatdest = laNone;
|
||||
}
|
||||
|
||||
bool applyCheat(char u, cell *c = NULL) {
|
||||
|
||||
if(u == 'L') {
|
||||
do {
|
||||
if(firstland == eLand(landtypes-1))
|
||||
firstland = eLand(2);
|
||||
else
|
||||
firstland = eLand(firstland+1);
|
||||
}
|
||||
while(isTechnicalLand(firstland) || isCyclic(firstland));
|
||||
specialland = firstland;
|
||||
cheater++; addMessage(XLAT("You will now start your games in %1", firstland));
|
||||
return true;
|
||||
}
|
||||
if(u == 'C') {
|
||||
cheater++;
|
||||
cheatMoveTo(laCrossroads);
|
||||
addMessage(XLAT("Activated the Hyperstone Quest!"));
|
||||
|
||||
for(int t=1; t<ittypes; t++)
|
||||
if(t != itHyperstone && t != itBounty && itemclass(eItem(t)) == IC_TREASURE) {
|
||||
items[t] = 10;
|
||||
}
|
||||
kills[moYeti] = 200;
|
||||
kills[moDesertman] = 200;
|
||||
kills[moRunDog] = 200;
|
||||
kills[moZombie] = 200;
|
||||
kills[moMonkey] = 200;
|
||||
kills[moCultist] = 200;
|
||||
kills[moTroll] = 200;
|
||||
return true;
|
||||
}
|
||||
if(u == 'M') {
|
||||
for(int i=0; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_ORB)
|
||||
items[i] = 0;
|
||||
cheater++; addMessage(XLAT("Orb power depleted!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'O') {
|
||||
cheater++; addMessage(XLAT("Orbs summoned!"));
|
||||
for(int i=0; i<cwt.c->type; i++)
|
||||
if(passable(cwt.c->mov[i], NULL, 0)) {
|
||||
eItem it = nextOrb();
|
||||
cwt.c->mov[i]->item = it;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'F') {
|
||||
if(hardcore && !canmove) {
|
||||
canmove = true;
|
||||
addMessage(XLAT("Revived!"));
|
||||
}
|
||||
else {
|
||||
items[itOrbFlash] += 1;
|
||||
items[itOrbTeleport] += 1;
|
||||
items[itOrbLightning] += 1;
|
||||
items[itOrbSpeed] += 1;
|
||||
items[itOrbShield] += 1;
|
||||
kills[moPlayer] = 0;
|
||||
cheater++; addMessage(XLAT("Orb power gained!"));
|
||||
canmove = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'D') {
|
||||
items[itGreenStone] += 10;
|
||||
cheater++; addMessage(XLAT("Dead orbs gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'R'-64) buildRosemap();
|
||||
#if CAP_EDIT
|
||||
if(u == 'A') {
|
||||
lastexplore = turncount;
|
||||
pushScreen(mapeditor::showMapEditor);
|
||||
return true;
|
||||
}
|
||||
if(u == 'A'-64) {
|
||||
mapeditor::drawcell = mouseover ? mouseover : cwt.c;
|
||||
pushScreen(mapeditor::showDrawEditor);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
if(u == 'T') {
|
||||
items[randomTreasure2(10)] += 10;
|
||||
cheater++; addMessage(XLAT("Treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'T'-64) {
|
||||
items[randomTreasure2(100)] += 100;
|
||||
cheater++; addMessage(XLAT("Lots of treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'I'-64) {
|
||||
items[randomTreasure2(10)] += 25;
|
||||
cheater++; addMessage(XLAT("Treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'U'-64) {
|
||||
items[randomTreasure2(10)] += 50;
|
||||
cheater++; addMessage(XLAT("Treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'Z') {
|
||||
flipplayer = false;
|
||||
mirror::act(1, mirror::SPINSINGLE);
|
||||
cwspin(cwt, 1);
|
||||
return true;
|
||||
}
|
||||
if(u == 'J') {
|
||||
if(items[localTreasureType()] > 0)
|
||||
items[localTreasureType()] = 0;
|
||||
else for(int i=1; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_TREASURE)
|
||||
items[i] = 0;
|
||||
cheater++; addMessage(XLAT("Treasure lost!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'K') {
|
||||
for(int i=0; i<motypes; i++) kills[i] += 10;
|
||||
kills[moPlayer] = 0;
|
||||
cheater++; addMessage(XLAT("Kills gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'Y') {
|
||||
for(auto& y: yendor::yi) {
|
||||
if(y.path[YDIST-1]->item == itKey)
|
||||
y.path[YDIST-1]->item = itNone;
|
||||
if(!y.found) items[itKey]++;
|
||||
y.found = true;
|
||||
}
|
||||
cheater++; addMessage(XLAT("Collected the keys!"));
|
||||
}
|
||||
if(u == 'P') {
|
||||
items[itSavedPrincess]++;
|
||||
princess::saved = true;
|
||||
princess::everSaved = true;
|
||||
if(inv::on && !princess::reviveAt)
|
||||
princess::reviveAt = gold(NO_LOVE);
|
||||
cheater++; addMessage(XLAT("Saved the Princess!"));
|
||||
}
|
||||
if(u == 'S') {
|
||||
canmove = true;
|
||||
cheatMoveTo(cwt.c->land);
|
||||
items[itOrbSafety] += 3;
|
||||
cheater++; addMessage(XLAT("Activated Orb of Safety!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'U') {
|
||||
canmove = true;
|
||||
cheatMoveTo(firstland);
|
||||
cheater++; addMessage(XLAT("Teleported to %1!", firstland));
|
||||
return true;
|
||||
}
|
||||
if(u == 'W'-64) {
|
||||
pushScreen(linepatterns::showMenu);
|
||||
return true;
|
||||
}
|
||||
if(u == 'G'-64) {
|
||||
timerghost = !timerghost;
|
||||
cheater++;
|
||||
addMessage(XLAT("turn count = %1 last exploration = %2 ghost timer = %3",
|
||||
its(turncount), its(lastexplore), ONOFF(timerghost)));
|
||||
return true;
|
||||
}
|
||||
if(u == 'L'-64) {
|
||||
cell *c = mouseover;
|
||||
describeCell(c);
|
||||
printf("Neighbors:"); for(int i=0; i<c->type; i++) printf("%p ", c->mov[i]);
|
||||
printf("Barrier: dir=%d left=%d right=%d\n",
|
||||
c->bardir, c->barleft, c->barright);
|
||||
return true;
|
||||
}
|
||||
if(u == 'C'-64) {
|
||||
cblind = !cblind;
|
||||
return true;
|
||||
}
|
||||
if(u == 'G') {
|
||||
pushScreen(debugScreen);
|
||||
return true;
|
||||
}
|
||||
if(u == 'P'-64)
|
||||
peace::on = !peace::on;
|
||||
#ifdef CHEAT_DISABLE_ALLOWED
|
||||
if(u == 'D'-64) {
|
||||
cheater = 0; autocheat = 0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T> string dnameof2(T x) {
|
||||
string s = dnameof(x);
|
||||
return s + " (" + its(x) + ")";
|
||||
}
|
||||
|
||||
template<class T> string dnameof2(T x, int p) {
|
||||
string s = dnameof(x);
|
||||
return s + " (" + its(x) + "/" + its(p) + ")";
|
||||
}
|
||||
|
||||
vector<pair<cellwalker,int> > drawbugs;
|
||||
|
||||
bool debugmode = false;
|
||||
|
||||
void debugScreen() {
|
||||
cmode = vid.xres > vid.yres * 1.4 ? sm::SIDE : 0;
|
||||
gamescreen(0);
|
||||
dialog::init(XLAT("debug"));
|
||||
|
||||
for(auto& p: drawbugs)
|
||||
drawBug(p.first, p.second);
|
||||
|
||||
if(mouseover) {
|
||||
drawBug(cellwalker(mouseover, 0), 0x80808080);
|
||||
char buf[200];
|
||||
sprintf(buf, "%p", mouseover);
|
||||
dialog::addSelItem("pointer", buf, 0);
|
||||
dialog::addSelItem("mpdist", its(mouseover->mpdist), 0);
|
||||
dialog::addSelItem("land", dnameof2(mouseover->land), 0);
|
||||
dialog::addSelItem("land param (int)", its(mouseover->landparam), 0);
|
||||
dialog::addSelItem("land param (hex)", itsh8(mouseover->landparam), 0);
|
||||
dialog::addSelItem("land param (heat)", fts(HEAT(mouseover)), 0);
|
||||
dialog::addSelItem("land flags", its(mouseover->landflags)+"/"+itsh2(mouseover->landflags), 0);
|
||||
dialog::addSelItem("barrier dir", its(mouseover->bardir), 0);
|
||||
dialog::addSelItem("barrier left", dnameof2(mouseover->barleft), 0);
|
||||
dialog::addSelItem("barrier right", dnameof2(mouseover->barright), 0);
|
||||
dialog::addBreak(50);
|
||||
dialog::addSelItem("wall", dnameof2(mouseover->wall, mouseover->wparam), 0);
|
||||
dialog::addSelItem("item", dnameof(mouseover->item), 0);
|
||||
dialog::addBreak(50);
|
||||
dialog::addSelItem("cpdist", its(mouseover->cpdist), 0);
|
||||
dialog::addSelItem("pathdist", its(mouseover->pathdist), 0);
|
||||
dialog::addSelItem("temporary", its(mouseover->aitmp), 0);
|
||||
dialog::addBreak(50);
|
||||
dialog::addSelItem("monster", dnameof2(mouseover->monst, mouseover->mondir), 0);
|
||||
dialog::addSelItem("stuntime/hitpoints", its(mouseover->stuntime)+"/"+its(mouseover->hitpoints), 0);
|
||||
}
|
||||
dialog::display();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
handlePanning(sym, uni);
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(applyCheat(uni, mouseover)) ;
|
||||
else if(sym == PSEUDOKEY_WHEELUP || sym == PSEUDOKEY_WHEELDOWN) ;
|
||||
else if(doexiton(sym, uni)) {
|
||||
popScreen();
|
||||
if(debugmode) quitmainloop = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// -- cheat menu --
|
||||
|
||||
void showCheatMenu() {
|
||||
gamescreen(1);
|
||||
dialog::init("cheat menu");
|
||||
dialog::addItem(XLAT("return to the game"), ' ');
|
||||
dialog::addBreak(50);
|
||||
dialog::addItem(XLAT("gain orb powers"), 'F');
|
||||
dialog::addItem(XLAT("summon treasure"), 'T');
|
||||
dialog::addItem(XLAT("summon dead orbs"), 'D');
|
||||
dialog::addItem(XLAT("lose all treasure"), 'J');
|
||||
dialog::addItem(XLAT("gain kills"), 'K');
|
||||
dialog::addItem(XLAT("Hyperstone Quest"), 'C');
|
||||
dialog::addItem(XLAT("summon orbs"), 'O');
|
||||
dialog::addItem(XLAT("gain Orb of Yendor"), 'Y');
|
||||
dialog::addItem(XLAT("summon lots of treasure"), 'T'-64);
|
||||
dialog::addItem(XLAT("Safety (quick save)"), 'S');
|
||||
dialog::addItem(XLAT("Select the land ---"), 'L');
|
||||
dialog::addItem(XLAT("--- and teleport there"), 'U');
|
||||
dialog::addItem(XLAT("rotate the character"), 'Z');
|
||||
dialog::addItem(XLAT("deplete orb powers"), 'M');
|
||||
dialog::addItem(XLAT("save a Princess"), 'P');
|
||||
dialog::addItem(XLAT("unlock Orbs of Yendor"), 'Y');
|
||||
dialog::addItem(XLAT("switch ghost timer"), 'G'-64);
|
||||
dialog::addItem(XLAT("switch web display"), 'W'-64);
|
||||
dialog::addItem(XLAT("peaceful mode"), 'P'-64);
|
||||
dialog::display();
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(uni != 0) {
|
||||
applyCheat(uni);
|
||||
if(uni == 'F' || uni == 'C' || uni == 'O' ||
|
||||
uni == 'S' || uni == 'U' || uni == 'G' ||
|
||||
uni == 'W' || uni == 'I' || uni == 'E' ||
|
||||
uni == 'H' || uni == 'B' || uni == 'M' ||
|
||||
uni == 'M' || uni == 'Y'-64 || uni == 'G'-64 ||
|
||||
uni == ' ' || uni == 8 || uni == 13 ||
|
||||
uni == SDLK_ESCAPE || uni == 'q' || uni == 'v' || sym == SDLK_ESCAPE ||
|
||||
sym == SDLK_F10)
|
||||
popScreen();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#ifdef BACKTRACE
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
void modalDebug(cell *c) {
|
||||
viewctr.h = c->master;
|
||||
pushScreen(debugScreen);
|
||||
debugmode = true;
|
||||
mainloop();
|
||||
debugmode = false;
|
||||
quitmainloop = false;
|
||||
}
|
||||
|
||||
void raiseBuggyGeneration(cell *c, const char *s) {
|
||||
|
||||
printf("procgen error (%p): %s\n", c, s);
|
||||
|
||||
if(!errorReported) {
|
||||
addMessage(string("something strange happened in: ") + s);
|
||||
errorReported = true;
|
||||
}
|
||||
|
||||
#ifdef BACKTRACE
|
||||
void *array[1000];
|
||||
size_t size;
|
||||
|
||||
// get void*'s for all entries on the stack
|
||||
size = backtrace(array, 1000);
|
||||
|
||||
// print out all the frames to stderr
|
||||
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
||||
#endif
|
||||
|
||||
// return;
|
||||
|
||||
if(cheater) {
|
||||
drawbugs.emplace_back(cellwalker(c,0), 0xFF000080);
|
||||
modalDebug(c);
|
||||
drawbugs.pop_back();
|
||||
}
|
||||
else
|
||||
c->item = itBuggy;
|
||||
}
|
48
dialogs.cpp
48
dialogs.cpp
@ -147,6 +147,19 @@ namespace dialog {
|
||||
items.push_back(it);
|
||||
}
|
||||
|
||||
void addBigItem(string body, int key) {
|
||||
item it;
|
||||
it.type = diBigItem;
|
||||
it.body = body;
|
||||
it.keycaption = keyname(key);
|
||||
it.key = key;
|
||||
it.color = 0xC06000;
|
||||
it.colors = 0xFFD500;
|
||||
it.colorc = 0xFF8000;
|
||||
it.scale = 150;
|
||||
items.push_back(it);
|
||||
}
|
||||
|
||||
int addBreak(int val) {
|
||||
item it;
|
||||
it.type = diBreak;
|
||||
@ -223,7 +236,7 @@ namespace dialog {
|
||||
tothei += dfspace * items[i].scale / 100;
|
||||
if(items[i].type == diItem)
|
||||
innerwidth = max(innerwidth, textwidth(dfsize * items[i].scale / 100, items[i].body));
|
||||
if(items[i].type == diTitle || items[i].type == diInfo)
|
||||
if(items[i].type == diTitle || items[i].type == diInfo || items[i].type == diBigItem)
|
||||
dialogwidth = max(dialogwidth, textwidth(dfsize * items[i].scale / 100, items[i].body) * 10/9);
|
||||
}
|
||||
}
|
||||
@ -287,7 +300,7 @@ namespace dialog {
|
||||
if(I.type == diTitle || I.type == diInfo) {
|
||||
displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8);
|
||||
}
|
||||
else if(I.type == diItem) {
|
||||
else if(I.type == diItem || I.type == diBigItem) {
|
||||
bool xthis = (mousey >= top && mousey < tothei);
|
||||
#if ISMOBILE
|
||||
if(xthis && mousepressed)
|
||||
@ -301,10 +314,15 @@ namespace dialog {
|
||||
I.color = (xthis&&mousepressed&&actonrelease) ? I.colorc : I.colors;
|
||||
}
|
||||
#endif
|
||||
if(!mousing)
|
||||
displayfr(keyx, mid, 2, dfsize * I.scale/100, I.keycaption, I.colork, 16);
|
||||
displayfr(itemx, mid, 2, dfsize * I.scale/100, I.body, I.color, 0);
|
||||
displayfr(valuex, mid, 2, dfsize * I.scale/100, I.value, I.colorv, 0);
|
||||
if(I.type == diBigItem) {
|
||||
displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8);
|
||||
}
|
||||
else {
|
||||
if(!mousing)
|
||||
displayfr(keyx, mid, 2, dfsize * I.scale/100, I.keycaption, I.colork, 16);
|
||||
displayfr(itemx, mid, 2, dfsize * I.scale/100, I.body, I.color, 0);
|
||||
displayfr(valuex, mid, 2, dfsize * I.scale/100, I.value, I.colorv, 0);
|
||||
}
|
||||
if(xthis) getcstat = I.key;
|
||||
}
|
||||
else if(I.type == diSlider) {
|
||||
@ -322,24 +340,28 @@ namespace dialog {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isitem(item& it) {
|
||||
return it.type == diItem || it.type == diBigItem;
|
||||
}
|
||||
|
||||
void handleNavigation(int &sym, int &uni) {
|
||||
#if !ISMOBILE
|
||||
if(uni == '\n' || uni == '\r' || sym == SDLK_KP5)
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem)
|
||||
if(isitem(items[i]))
|
||||
if(items[i].body == highlight_text) {
|
||||
uni = sym = items[i].key;
|
||||
return;
|
||||
}
|
||||
if(sym == SDLK_PAGEDOWN || sym == SDLK_KP3) {
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem)
|
||||
if(isitem(items[i]))
|
||||
highlight_text = items[i].body;
|
||||
}
|
||||
if(sym == SDLK_PAGEUP || sym == SDLK_KP9) {
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem) {
|
||||
if(isitem(items[i])) {
|
||||
highlight_text = items[i].body;
|
||||
break;
|
||||
}
|
||||
@ -347,11 +369,11 @@ namespace dialog {
|
||||
if(sym == SDLK_UP || sym == SDLK_KP8) {
|
||||
string last = "";
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem)
|
||||
if(isitem(items[i]))
|
||||
last = items[i].body;
|
||||
uni = sym = 0;
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem) {
|
||||
if(isitem(items[i])) {
|
||||
if(items[i].body == highlight_text) {
|
||||
highlight_text = last; return;
|
||||
}
|
||||
@ -362,12 +384,12 @@ namespace dialog {
|
||||
if(sym == SDLK_DOWN || sym == SDLK_KP2) {
|
||||
int state = 0;
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem) {
|
||||
if(isitem(items[i])) {
|
||||
if(state) { highlight_text = items[i].body; return; }
|
||||
else if(items[i].body == highlight_text) state = 1;
|
||||
}
|
||||
for(int i=0; i<size(items); i++)
|
||||
if(items[i].type == diItem)
|
||||
if(isitem(items[i]))
|
||||
highlight_text = items[i].body;
|
||||
uni = sym = 0;
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
const char *scorefile = "fakemobile_score.txt";
|
||||
const char *conffile = "fakemobile_config.txt";
|
||||
|
||||
#include <string>
|
||||
std::string levelfile = "fakemobile_level.txt";
|
||||
std::string picfile = "fakemobile_pic.txt";
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "init.cpp"
|
||||
|
72
game.cpp
72
game.cpp
@ -3601,6 +3601,35 @@ void explodeAround(cell *c) {
|
||||
}
|
||||
}
|
||||
|
||||
void killHardcorePlayer(int id, flagtype flags) {
|
||||
charstyle& cs = getcs(id);
|
||||
cell *c = playerpos(id);
|
||||
if(flags & AF_FALL)
|
||||
fallingMonsterAnimation(c, moPlayer);
|
||||
else for(int i=0; i<6; i++) {
|
||||
drawParticle(c, cs.skincolor >> 8, 100);
|
||||
drawParticle(c, cs.haircolor >> 8, 125);
|
||||
if(cs.charid)
|
||||
drawParticle(c, cs.dresscolor >> 8, 150);
|
||||
else
|
||||
drawParticle(c, cs.skincolor >> 8, 150);
|
||||
if(cs.charid == 3)
|
||||
drawParticle(c, cs.dresscolor2 >> 8, 175);
|
||||
else
|
||||
drawParticle(c, cs.skincolor >> 8, 150);
|
||||
drawParticle(c, cs.swordcolor >> 8, 200);
|
||||
}
|
||||
|
||||
if(multi::players > 1 && multi::activePlayers() > 1) {
|
||||
multi::leaveGame(id);
|
||||
}
|
||||
else {
|
||||
canmove = false;
|
||||
achievement_final(true);
|
||||
msgscroll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void killThePlayer(eMonster m, int id, flagtype flags) {
|
||||
if(markOrb(itOrbShield)) return;
|
||||
if(shmup::on) {
|
||||
@ -3619,13 +3648,7 @@ void killThePlayer(eMonster m, int id, flagtype flags) {
|
||||
}
|
||||
else if(hardcore) {
|
||||
addMessage(XLAT("You are killed by %the1!", m));
|
||||
if(multi::players > 1 && multi::activePlayers() > 1)
|
||||
multi::leaveGame(id);
|
||||
else {
|
||||
canmove = false;
|
||||
achievement_final(true);
|
||||
msgscroll = 0;
|
||||
}
|
||||
killHardcorePlayer(id, flags);
|
||||
}
|
||||
else if(m == moLightningBolt && lastmovetype == lmAttack && isAlchAny(playerpos(id))) {
|
||||
addMessage(XLAT("You are killed by %the1!", m));
|
||||
@ -5196,6 +5219,7 @@ void movemonsters() {
|
||||
bool checkNeedMove(bool checkonly, bool attacking) {
|
||||
if(items[itOrbDomination] > ORBBASE && cwt.c->monst)
|
||||
return false;
|
||||
int flags = 0;
|
||||
if(cwt.c->monst) {
|
||||
if(checkonly) return true;
|
||||
if(isMountable(cwt.c->monst))
|
||||
@ -5212,6 +5236,7 @@ bool checkNeedMove(bool checkonly, bool attacking) {
|
||||
if(markOrb2(itOrbAether)) return false;
|
||||
if(markOrb2(itOrbFish)) return false;
|
||||
if(checkonly) return true;
|
||||
flags |= AF_FALL;
|
||||
addMessage(XLAT("Ice below you is melting! RUN!"));
|
||||
}
|
||||
else if(!attacking && cellEdgeUnstable(cwt.c)) {
|
||||
@ -5238,6 +5263,7 @@ bool checkNeedMove(bool checkonly, bool attacking) {
|
||||
else if(cwt.c->wall == waChasm) {
|
||||
if(markOrb2(itOrbAether)) return false;
|
||||
if(checkonly) return true;
|
||||
flags |= AF_FALL;
|
||||
addMessage(XLAT("The floor has collapsed! RUN!"));
|
||||
}
|
||||
else if(items[itOrbAether] > ORBBASE && !passable(cwt.c, NULL, P_ISPLAYER | P_NOAETHER)) {
|
||||
@ -5251,12 +5277,8 @@ bool checkNeedMove(bool checkonly, bool attacking) {
|
||||
addMessage(XLAT("Your Aether power has expired! RUN!"));
|
||||
}
|
||||
else return false;
|
||||
if(hardcore) {
|
||||
canmove = false;
|
||||
achievement_final(true);
|
||||
msgscroll = 0;
|
||||
return false;
|
||||
}
|
||||
if(hardcore)
|
||||
killHardcorePlayer(multi::cpid, flags);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5389,7 +5411,7 @@ bool hasSafeOrb(cell *c) {
|
||||
c->item == itOrbSafety ||
|
||||
c->item == itOrbShield ||
|
||||
c->item == itOrbShell ||
|
||||
c->item == itOrbYendor;
|
||||
(c->item == itOrbYendor && yendor::state(c) == yendor::ysUnlocked);
|
||||
}
|
||||
|
||||
void checkmove() {
|
||||
@ -5592,8 +5614,10 @@ void collectMessage(cell *c2, eItem which) {
|
||||
addMessage(XLAT("This orb is dead..."));
|
||||
else if(which == itGreenStone)
|
||||
addMessage(XLAT("Another Dead Orb."));
|
||||
else if(itemclass(which) != IC_TREASURE)
|
||||
addMessage(XLAT("You have found %the1!", which));
|
||||
else if(itemclass(which) != IC_TREASURE) {
|
||||
if(c2->wall != waBoat)
|
||||
addMessage(XLAT("You have found %the1!", which));
|
||||
}
|
||||
else if(which == itBabyTortoise) {
|
||||
playSound(c2, playergender() ? "speak-princess" : "speak-prince");
|
||||
addMessage(XLAT("Aww, poor %1... where is your family?", which));
|
||||
@ -5639,6 +5663,18 @@ void collectMessage(cell *c2, eItem which) {
|
||||
else if(which == itPalace && items[itPalace] == U5-1 && !specialmode) {
|
||||
addMessage(XLAT("The rug depicts a man in a deep dungeon, unable to leave."));
|
||||
}
|
||||
else if(which == itFeather && items[itFeather] == 25-1 && !specialmode && inv::on)
|
||||
addMessage(XLAT("You feel the presence of free saves on the Crossroads."));
|
||||
else if(which == itHell && items[itHell] == 25-1 && !specialmode && inv::on)
|
||||
addMessage(XLAT("You feel the Orbs of Yendor nearby..."));
|
||||
else if(which == itHell && items[itHell] == 50-1 && !specialmode && inv::on)
|
||||
addMessage(XLAT("You feel the Orbs of Yendor in the Crossroads..."));
|
||||
else if(which == itHell && items[itHell] == 100-1 && !specialmode && inv::on)
|
||||
addMessage(XLAT("You feel the Orbs of Yendor everywhere..."));
|
||||
else if(which == itBone && items[itBone] % 25 == 24 && !specialmode && inv::on)
|
||||
addMessage(XLAT("You have gained an offensive power!"));
|
||||
else if(which == itHell && items[itHell] >= 100 && items[itHell] % 25 == 24 && !specialmode && inv::on)
|
||||
addMessage(XLAT("A small reward for braving the Hell."));
|
||||
else if(which == itIvory && items[itIvory] == U5-1 && !specialmode) {
|
||||
addMessage(XLAT("You feel attuned to gravity, ready to face mountains and dungeons."));
|
||||
}
|
||||
@ -5844,7 +5880,7 @@ bool collectItem(cell *c2, bool telekinesis) {
|
||||
addMessage(XLAT("The Orb of Safety from the Land of Eternal Motion might save you."));
|
||||
#endif
|
||||
|
||||
#define IF(x) if(pg < (x) && g2 >= x)
|
||||
#define IF(x) if(pg < (x) && g2 >= x && !peace::on)
|
||||
|
||||
IF(R60/4)
|
||||
addMessage(XLAT("Collect treasure to access more different lands..."));
|
||||
@ -6447,7 +6483,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
||||
placeWater(c2, cwt.c);
|
||||
moveBoat(c2, cwt.c);
|
||||
c2->mondir = neighborId(c2, cwt.c);
|
||||
if(cwt.c->item) moveItem(cwt.c, c2, false), boatmove = true;
|
||||
if(cwt.c->item) moveItem(cwt.c, c2, true), boatmove = true;
|
||||
goto boatjump;
|
||||
}
|
||||
|
||||
|
635
graph.cpp
635
graph.cpp
@ -48,10 +48,10 @@ string mouseovers;
|
||||
int darken = 0;
|
||||
|
||||
struct fallanim {
|
||||
int t_mon, t_floor;
|
||||
int t_mon, t_floor, pid;
|
||||
eWall walltype;
|
||||
eMonster m;
|
||||
fallanim() { t_floor = 0; t_mon = 0; walltype = waNone; }
|
||||
fallanim() { t_floor = 0; t_mon = 0; pid = 0; walltype = waNone; }
|
||||
};
|
||||
|
||||
map<cell*, fallanim> fallanims;
|
||||
@ -551,9 +551,22 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
|
||||
}
|
||||
|
||||
else if(it == itCompass) {
|
||||
cell *c1 = findcompass(c);
|
||||
transmatrix V2;
|
||||
if(euclid) V2 = V * spin(M_PI/2); // todo incorrect
|
||||
else V2 = V * rspintox(inverse(V) * pirateCoords);
|
||||
if(c1) {
|
||||
transmatrix P = shmup::ggmatrix(c1);
|
||||
hyperpoint P1 = tC0(P);
|
||||
|
||||
if(isPlayerOn(c)) {
|
||||
queuechr(P1, 2*vid.fsize, 'X', 0x10100 * int(128 + 100 * sin(ticks / 150.)));
|
||||
// queuestr(V, 1, its(compassDist(c)), 0x10101 * int(128 - 100 * sin(ticks / 150.)), 1);
|
||||
queuestr(P1, vid.fsize, its(-compassDist(c)), 0x10101 * int(128 - 100 * sin(ticks / 150.)));
|
||||
addauraspecial(P1, 0x0000FF, 0);
|
||||
}
|
||||
|
||||
V2 = V * rspintox(inverse(V) * P1);
|
||||
}
|
||||
else V2 = V;
|
||||
V2 = V2 * spin(M_PI * sin(ticks/100.) / 30);
|
||||
queuepoly(V2, shCompass1, 0xFF8080FF);
|
||||
queuepoly(V2, shCompass2, 0xFFFFFFFF);
|
||||
@ -1764,7 +1777,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
||||
return drawMonsterTypeDH(m, c, Vs, col, darkhistory, footphase);
|
||||
}
|
||||
|
||||
for(int i=0; i<numplayers(); i++) if(c == playerpos(i) && !shmup::on && mapeditor::drawplayer) {
|
||||
for(int i=0; i<numplayers(); i++) if(c == playerpos(i) && !shmup::on && mapeditor::drawplayer &&
|
||||
!(hardcore && !canmove)) {
|
||||
if(!nospins) {
|
||||
Vs = playerV;
|
||||
if(multi::players > 1 ? multi::flipped[i] : flipplayer) Vs = Vs * pispin;
|
||||
@ -1789,15 +1803,9 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool showPirateX;
|
||||
cell *keycell, *pirateTreasureSeek, *pirateTreasureFound;
|
||||
hyperpoint pirateCoords;
|
||||
|
||||
double downspin;
|
||||
cell *straightDownSeek;
|
||||
|
||||
int keycelldist;
|
||||
|
||||
#define AURA 180
|
||||
|
||||
int aurac[AURA+1][4];
|
||||
@ -1806,16 +1814,28 @@ bool haveaura() {
|
||||
return pmodel == mdDisk && (!sphere || vid.alpha > 10) && !euclid && vid.aurastr>0 && !svg::in && (auraNOGL || vid.usingGL);
|
||||
}
|
||||
|
||||
vector<pair<int, int> > auraspecials;
|
||||
|
||||
int auramemo;
|
||||
|
||||
void clearaura() {
|
||||
if(!haveaura()) return;
|
||||
for(int a=0; a<AURA; a++) for(int b=0; b<4; b++)
|
||||
aurac[a][b] = 0;
|
||||
auraspecials.clear();
|
||||
auramemo = 128 * 128 / vid.aurastr;
|
||||
}
|
||||
|
||||
void addauraspecial(const hyperpoint& h, int col, int dir) {
|
||||
if(!haveaura()) return;
|
||||
int r = int(2*AURA + dir + atan2(h[0], h[1]) * AURA / 2 / M_PI) % AURA;
|
||||
auraspecials.emplace_back(r, col);
|
||||
}
|
||||
|
||||
void addaura(const hyperpoint& h, int col, int fd) {
|
||||
if(!haveaura()) return;
|
||||
int r = int(2*AURA + atan2(h[0], h[1]) * AURA / 2 / M_PI) % AURA;
|
||||
aurac[r][3] += ((128 * 128 / vid.aurastr) << fd);
|
||||
aurac[r][3] += auramemo << fd;
|
||||
col = darkened(col);
|
||||
aurac[r][0] += (col>>16)&255;
|
||||
aurac[r][1] += (col>>8)&255;
|
||||
@ -1845,6 +1865,11 @@ void drawaura() {
|
||||
if(sphere) rad /= sqrt(vid.alphax*vid.alphax - 1);
|
||||
|
||||
for(int v=0; v<4; v++) sumaura(v);
|
||||
for(auto& p: auraspecials) {
|
||||
int r = p.first;
|
||||
aurac[r][3] = auramemo;
|
||||
for(int k=0; k<3; k++) aurac[r][k] = (p.second >> (8*k)) & 255;
|
||||
}
|
||||
|
||||
#if CAP_SDL || CAP_GL
|
||||
double bak[3];
|
||||
@ -2242,212 +2267,8 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
|
||||
wcol = fcol = winf[c->wall].color;
|
||||
|
||||
// floor colors for all the lands
|
||||
if(c->land == laKraken) fcol = 0x20A020;
|
||||
if(c->land == laBurial) fcol = linf[laBurial].color;
|
||||
if(c->land == laTrollheim) fcol = linf[c->land].color;
|
||||
|
||||
if(c->land == laBarrier) fcol = linf[c->land].color;
|
||||
if(c->land == laOceanWall) fcol = linf[c->land].color;
|
||||
|
||||
if(c->land == laAlchemist) {
|
||||
fcol = 0x202020;
|
||||
if(c->item && !(conformal::includeHistory && eq(c->aitmp, sval)))
|
||||
fcol = wcol = iinf[c->item].color;
|
||||
}
|
||||
|
||||
if(c->land == laBull)
|
||||
fcol = 0x800080;
|
||||
|
||||
if(c->land == laCA)
|
||||
fcol = 0x404040;
|
||||
|
||||
if(c->land == laReptile) {
|
||||
fcol = reptilecolor(c);
|
||||
}
|
||||
|
||||
if(c->land == laCrossroads) fcol = (vid.goteyes2 ? 0xFF3030 : 0xFF0000);
|
||||
if(c->land == laCrossroads2) fcol = linf[laCrossroads2].color;
|
||||
if(c->land == laCrossroads3) fcol = linf[laCrossroads3].color;
|
||||
if(c->land == laCrossroads4) fcol = linf[laCrossroads4].color;
|
||||
if(c->land == laCrossroads5) fcol = linf[laCrossroads5].color;
|
||||
if(isElemental(c->land)) fcol = linf[c->land].color;
|
||||
if(c->land == laDesert) fcol = 0xEDC9AF;
|
||||
if(c->land == laCaves) fcol = 0x202020;
|
||||
if(c->land == laEmerald) fcol = 0x202020;
|
||||
if(c->land == laDeadCaves) fcol = 0x202020;
|
||||
if(c->land == laJungle) fcol = (vid.goteyes2 ? 0x408040 : 0x008000);
|
||||
if(c->land == laMountain) {
|
||||
if(euclid || c->master->alt)
|
||||
fcol = celldistAlt(c) & 1 ? 0x604020 : 0x302010;
|
||||
else fcol = 0;
|
||||
if(c->wall == waPlatform) wcol = 0xF0F0A0;
|
||||
}
|
||||
if(c->land == laWineyard) fcol = 0x006000;
|
||||
if(c->land == laMirror || c->land == laMirrorWall || c->land == laMirrorOld)
|
||||
fcol = 0x808080;
|
||||
if(c->land == laMotion) fcol = 0xF0F000;
|
||||
if(c->land == laGraveyard) fcol = 0x107010;
|
||||
if(c->land == laDryForest) fcol = gradient(0x008000, 0x800000, 0, c->landparam, 10);
|
||||
if(c->land == laRlyeh) fcol = (vid.goteyes2 ? 0x4080C0 : 0x004080);
|
||||
if(c->land == laPower) fcol = linf[c->land].color;
|
||||
if(c->land == laHell) fcol = (vid.goteyes2 ? 0xC03030 : 0xC00000);
|
||||
if(c->land == laLivefjord) fcol = 0x306030;
|
||||
if(c->land == laWildWest) fcol = linf[c->land].color;
|
||||
if(c->land == laHalloween) fcol = linf[c->land].color;
|
||||
if(c->land == laMinefield) fcol = 0x80A080;
|
||||
if(c->land == laCaribbean) fcol = 0x006000;
|
||||
if(c->land == laRose) fcol = linf[c->land].color;
|
||||
if(c->land == laCanvas) fcol = c->landparam;
|
||||
if(c->land == laRedRock) fcol = linf[c->land].color;
|
||||
if(c->land == laDragon) fcol = linf[c->land].color;
|
||||
if(c->land == laStorms) fcol = linf[c->land].color;
|
||||
|
||||
if(c->land == laPalace) {
|
||||
fcol = 0x806020;
|
||||
if(c->wall == waClosedGate || c->wall == waOpenGate)
|
||||
fcol = wcol;
|
||||
}
|
||||
|
||||
if(c->land == laElementalWall)
|
||||
fcol = (linf[c->barleft].color>>1) + (linf[c->barright].color>>1);
|
||||
|
||||
if(c->land == laZebra) {
|
||||
fcol = 0xE0E0E0;
|
||||
if(c->wall == waTrapdoor) fcol = 0x808080;
|
||||
}
|
||||
|
||||
if(c->land == laCaribbean && (c->wall == waCIsland || c->wall == waCIsland2))
|
||||
fcol = wcol = winf[c->wall].color;
|
||||
|
||||
if(isHive(c->land)) {
|
||||
fcol = linf[c->land].color;
|
||||
if(c->wall == waWaxWall) wcol = c->landparam;
|
||||
if(items[itOrbInvis] && c->wall == waNone && c->landparam)
|
||||
fcol = gradient(fcol, 0xFF0000, 0, c->landparam, 100);
|
||||
if(c->bardir == NOBARRIERS && c->barleft)
|
||||
fcol = minf[moBug0+c->barright].color;
|
||||
}
|
||||
|
||||
if(isWarped(c->land)) {
|
||||
fcol = pseudohept(c) ? 0x80C080 : 0xA06020;
|
||||
if(c->wall == waSmallTree) wcol = 0x608000;
|
||||
}
|
||||
|
||||
if(c->land == laTortoise) {
|
||||
fcol = tortoise::getMatchColor(getBits(c));
|
||||
if(c->wall == waBigTree) wcol = 0x709000;
|
||||
else if(c->wall == waSmallTree) wcol = 0x905000;
|
||||
}
|
||||
|
||||
if(c->land == laOvergrown || c->land == laClearing) {
|
||||
fcol = (c->land == laOvergrown/* || (celldistAlt(c)&1)*/) ? 0x00C020 : 0x60E080;
|
||||
if(c->wall == waSmallTree) wcol = 0x008060;
|
||||
else if(c->wall == waBigTree) wcol = 0x0080C0;
|
||||
}
|
||||
|
||||
if(c->land == laTemple) {
|
||||
int d = showoff ? 0 : (euclid||c->master->alt) ? celldistAlt(c) : 99;
|
||||
if(chaosmode)
|
||||
fcol = 0x405090;
|
||||
else if(d % TEMPLE_EACH == 0)
|
||||
fcol = gradient(0x304080, winf[waColumn].color, 0, 0.5, 1);
|
||||
// else if(c->type == 7)
|
||||
// wcol = 0x707070;
|
||||
else if(d% 2 == -1)
|
||||
fcol = 0x304080;
|
||||
else
|
||||
fcol = 0x405090;
|
||||
}
|
||||
|
||||
if(isHaunted(c->land)) {
|
||||
int itcolor = 0;
|
||||
for(int i=0; i<c->type; i++) if(c->mov[i] && c->mov[i]->item)
|
||||
itcolor = 1;
|
||||
if(c->item) itcolor |= 2;
|
||||
fcol = 0x609F60 + 0x202020 * itcolor;
|
||||
|
||||
forCellEx(c2, c) if(c2->monst == moFriendlyGhost)
|
||||
fcol = gradient(fcol, fghostcolor(ticks, c2), 0, .25, 1);
|
||||
|
||||
if(c->monst == moFriendlyGhost)
|
||||
fcol = gradient(fcol, fghostcolor(ticks, c), 0, .5, 1);
|
||||
|
||||
if(c->wall == waSmallTree) wcol = 0x004000;
|
||||
else if(c->wall == waBigTree) wcol = 0x008000;
|
||||
}
|
||||
|
||||
if(c->land == laCamelot) {
|
||||
int d = showoff ? 0 : ((euclid||c->master->alt) ? celldistAltRelative(c) : 0);
|
||||
#if CAP_TOUR
|
||||
if(!tour::on) camelotcheat = false;
|
||||
if(camelotcheat)
|
||||
fcol = (d&1) ? 0xC0C0C0 : 0x606060;
|
||||
else
|
||||
#endif
|
||||
if(d < 0) {
|
||||
fcol = 0xA0A0A0;
|
||||
}
|
||||
else {
|
||||
// a nice floor pattern
|
||||
int v = emeraldval(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)
|
||||
fcol = 0xC0C0C0;
|
||||
else
|
||||
fcol = 0xA0A0A0;
|
||||
}
|
||||
}
|
||||
|
||||
if(c->land == laPrairie) {
|
||||
/* if(isWateryOrBoat(c)) {
|
||||
if(prairie::isriver(c))
|
||||
fcol = ((c->LHU.fi.rval & 1) ? 0x000090 : 0x0000E0)
|
||||
+ int(16 * wavefun(ticks / 200. + (c->wparam)*1.5))
|
||||
+ ((prairie::next(c) ? 0 : 0xC00000));
|
||||
else
|
||||
fcol = 0x000080;
|
||||
} */
|
||||
|
||||
if(prairie::isriver(c)) {
|
||||
fcol = ((c->LHU.fi.rval & 1) ? 0x402000: 0x503000);
|
||||
}
|
||||
else {
|
||||
fcol = 0x004000 + 0x001000 * c->LHU.fi.walldist;
|
||||
fcol += 0x10000 * (255 - 511 / (1 + max((int) c->LHU.fi.flowerdist, 1)));
|
||||
// fcol += 0x1 * (511 / (1 + max((int) c->LHU.fi.walldist2, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
else if(isIcyLand(c) && isIcyWall(c)) {
|
||||
float h = HEAT(c);
|
||||
bool showcoc = c->land == laCocytus && chaosmode && !wmescher;
|
||||
if(h < -0.4)
|
||||
wcol = gradient(showcoc ? 0x4080FF : 0x4040FF, 0x0000FF, -0.4, h, -1);
|
||||
else if(h < 0)
|
||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, showcoc ? 0x4080FF : 0x4040FF, 0, h, -0.4);
|
||||
else if(h < 0.2)
|
||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, 0xFFFFFF, 0, h, 0.2);
|
||||
// else if(h < 0.4)
|
||||
// wcol = gradient(0xFFFFFF, 0xFFFF00, 0.2, h, 0.4);
|
||||
else if(h < 0.6)
|
||||
wcol = gradient(0xFFFFFF, 0xFF0000, 0.2, h, 0.6);
|
||||
else if(h < 0.8)
|
||||
wcol = gradient(0xFF0000, 0xFFFF00, 0.6, h, 0.8);
|
||||
else
|
||||
wcol = 0xFFFF00;
|
||||
if(c->wall == waFrozenLake)
|
||||
fcol = wcol;
|
||||
else
|
||||
fcol = (wcol & 0xFEFEFE) >> 1;
|
||||
if(c->wall == waLake)
|
||||
fcol = wcol = (wcol & 0xFCFCFC) >> 2;
|
||||
}
|
||||
|
||||
else if(isWateryOrBoat(c) || c->wall == waReptileBridge) {
|
||||
// water colors
|
||||
if(isWateryOrBoat(c) || c->wall == waReptileBridge) {
|
||||
if(c->land == laOcean)
|
||||
fcol = (c->landparam > 25 && !chaosmode) ? 0x000090 :
|
||||
0x1010C0 + int(32 * sin(ticks / 500. + (chaosmode ? c->CHAOSPARAM : c->landparam)*1.5));
|
||||
@ -2474,56 +2295,259 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
else
|
||||
fcol = wcol;
|
||||
}
|
||||
|
||||
else if(c->land == laOcean) {
|
||||
if(chaosmode)
|
||||
fcol = gradient(0xD0A090, 0xD0D020, 0, c->CHAOSPARAM, 30);
|
||||
else
|
||||
fcol = gradient(0xD0D090, 0xD0D020, -1, sin((double) c->landparam), 1);
|
||||
}
|
||||
|
||||
if(c->land == laEmerald) {
|
||||
if(c->wall == waCavefloor || c->wall == waCavewall) {
|
||||
fcol = wcol = gradient(winf[waCavefloor].color, 0xFF00, 0, 0.5, 1);
|
||||
if(c->wall == waCavewall) wcol = 0xC0FFC0;
|
||||
// floor colors for all the lands
|
||||
else switch(c->land) {
|
||||
case laBurial: case laTrollheim: case laBarrier: case laOceanWall:
|
||||
case laCrossroads2: case laCrossroads3: case laCrossroads4: case laCrossroads5:
|
||||
case laRose: case laPower: case laWildWest: case laHalloween: case laRedRock:
|
||||
case laDragon: case laStorms:
|
||||
fcol = linf[c->land].color; break;
|
||||
|
||||
case laDesert: fcol = 0xEDC9AF; break;
|
||||
case laKraken: fcol = 0x20A020; break;
|
||||
case laCA: fcol = 0x404040; break;
|
||||
case laMotion: fcol = 0xF0F000; break;
|
||||
case laGraveyard: fcol = 0x107010; break;
|
||||
case laWineyard: fcol = 0x006000; break;
|
||||
case laLivefjord: fcol = 0x306030; break;
|
||||
|
||||
case laMinefield:
|
||||
fcol = 0x80A080;
|
||||
if(c->wall == waMineMine && ((cmode & sm::MAP) || !canmove))
|
||||
fcol = wcol = 0xFF4040;
|
||||
break;
|
||||
|
||||
case laCaribbean:
|
||||
if(c->wall != waCIsland && c->wall != waCIsland2)
|
||||
fcol = 0x006000;
|
||||
break;
|
||||
|
||||
case laAlchemist:
|
||||
fcol = 0x202020;
|
||||
if(c->item && !(conformal::includeHistory && eq(c->aitmp, sval)))
|
||||
fcol = wcol = iinf[c->item].color;
|
||||
break;
|
||||
case laReptile:
|
||||
fcol = reptilecolor(c);
|
||||
break;
|
||||
case laCrossroads:
|
||||
fcol = (vid.goteyes2 ? 0xFF3030 : 0xFF0000);
|
||||
break;
|
||||
case laCaves: case laEmerald: case laDeadCaves:
|
||||
fcol = 0x202020;
|
||||
if(c->land == laEmerald)
|
||||
if(c->wall == waCavefloor || c->wall == waCavewall) {
|
||||
fcol = wcol = gradient(winf[waCavefloor].color, 0xFF00, 0, 0.5, 1);
|
||||
if(c->wall == waCavewall) wcol = 0xC0FFC0;
|
||||
}
|
||||
break;
|
||||
case laJungle:
|
||||
fcol = (vid.goteyes2 ? 0x408040 : 0x008000);
|
||||
break;
|
||||
case laMirror: case laMirrorWall: case laMirrorOld:
|
||||
fcol = 0x808080;
|
||||
break;
|
||||
case laDryForest:
|
||||
fcol = gradient(0x008000, 0x800000, 0, c->landparam, 10);
|
||||
break;
|
||||
case laMountain:
|
||||
if(euclid || c->master->alt)
|
||||
fcol = celldistAlt(c) & 1 ? 0x604020 : 0x302010;
|
||||
else fcol = 0;
|
||||
if(c->wall == waPlatform) wcol = 0xF0F0A0;
|
||||
break;
|
||||
case laRlyeh:
|
||||
fcol = (vid.goteyes2 ? 0x4080C0 : 0x004080);
|
||||
break;
|
||||
case laHell:
|
||||
fcol = (vid.goteyes2 ? 0xC03030 : 0xC00000);
|
||||
break;
|
||||
case laCanvas:
|
||||
fcol = c->landparam;
|
||||
break;
|
||||
case laPalace:
|
||||
fcol = 0x806020;
|
||||
if(c->wall == waClosedGate || c->wall == waOpenGate)
|
||||
fcol = wcol;
|
||||
break;
|
||||
case laElementalWall:
|
||||
fcol = (linf[c->barleft].color>>1) + (linf[c->barright].color>>1);
|
||||
break;
|
||||
case laZebra:
|
||||
fcol = 0xE0E0E0;
|
||||
if(c->wall == waTrapdoor) fcol = 0x808080;
|
||||
break;
|
||||
case laHive:
|
||||
fcol = linf[c->land].color;
|
||||
if(c->wall == waWaxWall) wcol = c->landparam;
|
||||
if(items[itOrbInvis] && c->wall == waNone && c->landparam)
|
||||
fcol = gradient(fcol, 0xFF0000, 0, c->landparam, 100);
|
||||
if(c->bardir == NOBARRIERS && c->barleft)
|
||||
fcol = minf[moBug0+c->barright].color;
|
||||
break;
|
||||
case laTortoise:
|
||||
fcol = tortoise::getMatchColor(getBits(c));
|
||||
if(c->wall == waBigTree) wcol = 0x709000;
|
||||
else if(c->wall == waSmallTree) wcol = 0x905000;
|
||||
break;
|
||||
case laOvergrown: case laClearing:
|
||||
fcol = (c->land == laOvergrown/* || (celldistAlt(c)&1)*/) ? 0x00C020 : 0x60E080;
|
||||
if(c->wall == waSmallTree) wcol = 0x008060;
|
||||
else if(c->wall == waBigTree) wcol = 0x0080C0;
|
||||
break;
|
||||
case laTemple: {
|
||||
int d = showoff ? 0 : (euclid||c->master->alt) ? celldistAlt(c) : 99;
|
||||
if(chaosmode)
|
||||
fcol = 0x405090;
|
||||
else if(d % TEMPLE_EACH == 0)
|
||||
fcol = gradient(0x304080, winf[waColumn].color, 0, 0.5, 1);
|
||||
// else if(c->type == 7)
|
||||
// wcol = 0x707070;
|
||||
else if(d% 2 == -1)
|
||||
fcol = 0x304080;
|
||||
else
|
||||
fcol = 0x405090;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(c->land == laWhirlwind) {
|
||||
int wcol[4] = {0x404040, 0x404080, 0x2050A0, 0x5050C0};
|
||||
fcol = wcol[whirlwind::fzebra3(c)];
|
||||
}
|
||||
|
||||
if(c->land == laIvoryTower)
|
||||
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
||||
case laWhirlwind:
|
||||
if(c->land == laWhirlwind) {
|
||||
int wcol[4] = {0x404040, 0x404080, 0x2050A0, 0x5050C0};
|
||||
fcol = wcol[whirlwind::fzebra3(c)];
|
||||
}
|
||||
break;
|
||||
|
||||
if(c->land == laDungeon) {
|
||||
int lp = c->landparam % 5;
|
||||
// xcol = (c->landparam&1) ? 0xD00000 : 0x00D000;
|
||||
int lps[5] = { 0x402000, 0x302000, 0x202000, 0x282000, 0x382000 };
|
||||
fcol = lps[lp];
|
||||
if(c->wall == waClosedGate)
|
||||
fcol = wcol = 0xC0C0C0;
|
||||
if(c->wall == waOpenGate)
|
||||
fcol = wcol = 0x404040;
|
||||
if(c->wall == waPlatform)
|
||||
fcol = wcol = 0xDFB520;
|
||||
}
|
||||
|
||||
if(c->land == laEndorian) {
|
||||
int clev = cwt.c->land == laEndorian ? edgeDepth(cwt.c) : 0;
|
||||
// xcol = (c->landparam&1) ? 0xD00000 : 0x00D000;
|
||||
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
||||
fcol = gradient(fcol, 0x0000D0, clev-10, edgeDepth(c), clev+10);
|
||||
if(c->wall == waTrunk) fcol = winf[waTrunk].color;
|
||||
|
||||
if(c->wall == waCanopy || c->wall == waSolidBranch || c->wall == waWeakBranch) {
|
||||
fcol = winf[waCanopy].color;
|
||||
if(c->landparam & 1) fcol = gradient(0, fcol, 0, .75, 1);
|
||||
case laIvoryTower:
|
||||
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
||||
break;
|
||||
|
||||
case laDungeon: {
|
||||
int lp = c->landparam % 5;
|
||||
// xcol = (c->landparam&1) ? 0xD00000 : 0x00D000;
|
||||
int lps[5] = { 0x402000, 0x302000, 0x202000, 0x282000, 0x382000 };
|
||||
fcol = lps[lp];
|
||||
if(c->wall == waClosedGate)
|
||||
fcol = wcol = 0xC0C0C0;
|
||||
if(c->wall == waOpenGate)
|
||||
fcol = wcol = 0x404040;
|
||||
if(c->wall == waPlatform)
|
||||
fcol = wcol = 0xDFB520;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
case laEndorian: {
|
||||
int clev = cwt.c->land == laEndorian ? edgeDepth(cwt.c) : 0;
|
||||
// xcol = (c->landparam&1) ? 0xD00000 : 0x00D000;
|
||||
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
||||
fcol = gradient(fcol, 0x0000D0, clev-10, edgeDepth(c), clev+10);
|
||||
if(c->wall == waTrunk) fcol = winf[waTrunk].color;
|
||||
|
||||
if(c->wall == waCanopy || c->wall == waSolidBranch || c->wall == waWeakBranch) {
|
||||
fcol = winf[waCanopy].color;
|
||||
if(c->landparam & 1) fcol = gradient(0, fcol, 0, .75, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case laPrairie:
|
||||
if(prairie::isriver(c)) {
|
||||
fcol = ((c->LHU.fi.rval & 1) ? 0x402000: 0x503000);
|
||||
}
|
||||
else {
|
||||
fcol = 0x004000 + 0x001000 * c->LHU.fi.walldist;
|
||||
fcol += 0x10000 * (255 - 511 / (1 + max((int) c->LHU.fi.flowerdist, 1)));
|
||||
// fcol += 0x1 * (511 / (1 + max((int) c->LHU.fi.walldist2, 1)));
|
||||
}
|
||||
break;
|
||||
|
||||
case laCamelot: {
|
||||
int d = showoff ? 0 : ((euclid||c->master->alt) ? celldistAltRelative(c) : 0);
|
||||
#if CAP_TOUR
|
||||
if(!tour::on) camelotcheat = false;
|
||||
if(camelotcheat)
|
||||
fcol = (d&1) ? 0xC0C0C0 : 0x606060;
|
||||
else
|
||||
#endif
|
||||
if(d < 0) {
|
||||
fcol = 0xA0A0A0;
|
||||
}
|
||||
else {
|
||||
// a nice floor pattern
|
||||
int v = emeraldval(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)
|
||||
fcol = 0xC0C0C0;
|
||||
else
|
||||
fcol = 0xA0A0A0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case laIce: case laCocytus:
|
||||
if(isIcyWall(c)) {
|
||||
float h = HEAT(c);
|
||||
bool showcoc = c->land == laCocytus && chaosmode && !wmescher;
|
||||
if(h < -0.4)
|
||||
wcol = gradient(showcoc ? 0x4080FF : 0x4040FF, 0x0000FF, -0.4, h, -1);
|
||||
else if(h < 0)
|
||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, showcoc ? 0x4080FF : 0x4040FF, 0, h, -0.4);
|
||||
else if(h < 0.2)
|
||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, 0xFFFFFF, 0, h, 0.2);
|
||||
// else if(h < 0.4)
|
||||
// wcol = gradient(0xFFFFFF, 0xFFFF00, 0.2, h, 0.4);
|
||||
else if(h < 0.6)
|
||||
wcol = gradient(0xFFFFFF, 0xFF0000, 0.2, h, 0.6);
|
||||
else if(h < 0.8)
|
||||
wcol = gradient(0xFF0000, 0xFFFF00, 0.6, h, 0.8);
|
||||
else
|
||||
wcol = 0xFFFF00;
|
||||
if(c->wall == waFrozenLake)
|
||||
fcol = wcol;
|
||||
else
|
||||
fcol = (wcol & 0xFEFEFE) >> 1;
|
||||
if(c->wall == waLake)
|
||||
fcol = wcol = (wcol & 0xFCFCFC) >> 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case laOcean:
|
||||
if(chaosmode)
|
||||
fcol = gradient(0xD0A090, 0xD0D020, 0, c->CHAOSPARAM, 30);
|
||||
else
|
||||
fcol = gradient(0xD0D090, 0xD0D020, -1, sin((double) c->landparam), 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(isElemental(c->land)) fcol = linf[c->land].color;
|
||||
if(isWarped(c->land)) {
|
||||
fcol = pseudohept(c) ? 0x80C080 : 0xA06020;
|
||||
if(c->wall == waSmallTree) wcol = 0x608000;
|
||||
}
|
||||
if(isHaunted(c->land)) {
|
||||
int itcolor = 0;
|
||||
for(int i=0; i<c->type; i++) if(c->mov[i] && c->mov[i]->item)
|
||||
itcolor = 1;
|
||||
if(c->item) itcolor |= 2;
|
||||
fcol = 0x609F60 + 0x202020 * itcolor;
|
||||
|
||||
forCellEx(c2, c) if(c2->monst == moFriendlyGhost)
|
||||
fcol = gradient(fcol, fghostcolor(ticks, c2), 0, .25, 1);
|
||||
|
||||
if(c->monst == moFriendlyGhost)
|
||||
fcol = gradient(fcol, fghostcolor(ticks, c), 0, .5, 1);
|
||||
|
||||
if(c->wall == waSmallTree) wcol = 0x004000;
|
||||
else if(c->wall == waBigTree) wcol = 0x008000;
|
||||
}
|
||||
}
|
||||
|
||||
/* if(c->land == laCaribbean && (c->wall == waCIsland || c->wall == waCIsland2))
|
||||
fcol = wcol = winf[c->wall].color; */
|
||||
|
||||
// floors become fcol
|
||||
if(c->wall == waSulphur || c->wall == waSulphurC || isAlch(c) || c->wall == waPlatform)
|
||||
fcol = wcol;
|
||||
@ -2554,9 +2578,6 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
if(c->wall == waAncientGrave || c->wall == waFreshGrave || c->wall == waThumperOn || c->wall == waThumperOff || c->wall == waBonfireOff)
|
||||
fcol = wcol;
|
||||
|
||||
if(c->land == laMinefield && c->wall == waMineMine && ((cmode & sm::MAP) || !canmove))
|
||||
fcol = wcol = 0xFF4040;
|
||||
|
||||
if(mightBeMine(c) && mineMarkedSafe(c))
|
||||
fcol = wcol = gradient(wcol, 0x40FF40, 0, 0.2, 1);
|
||||
|
||||
@ -2796,7 +2817,7 @@ void pushdown(cell *c, int& q, const transmatrix &V, double down, bool rezoom, b
|
||||
|
||||
bool dodrawcell(cell *c) {
|
||||
// todo: fix when scrolling
|
||||
if(!buggyGeneration && c->land != laCanvas && sightrange < 10) {
|
||||
if(!buggyGeneration && !debugmode && c->land != laCanvas && sightrange < 10) {
|
||||
// not yet created
|
||||
if(c->mpdist > 7 && !cheater) return false;
|
||||
// in the Yendor Challenge, scrolling back is forbidden
|
||||
@ -3913,6 +3934,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
}
|
||||
}
|
||||
if(fa.t_mon) {
|
||||
dynamicval<int> d(multi::cpid, fa.pid);
|
||||
int t = (ticks - fa.t_mon);
|
||||
if(t <= 1500) {
|
||||
erase = false;
|
||||
@ -4072,9 +4094,6 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
vid.linewidth /= 3;
|
||||
}
|
||||
|
||||
if(!euclid && (!pirateTreasureSeek || compassDist(c) < compassDist(pirateTreasureSeek)))
|
||||
pirateTreasureSeek = c;
|
||||
|
||||
if(!euclid) {
|
||||
bool usethis = false;
|
||||
double spd = 1;
|
||||
@ -4190,11 +4209,12 @@ void fallingFloorAnimation(cell *c, eWall w, eMonster m) {
|
||||
fa.walltype = w; fa.m = m;
|
||||
// drawParticles(c, darkenedby(linf[c->land].color, 1), 4, 50);
|
||||
}
|
||||
void fallingMonsterAnimation(cell *c, eMonster m) {
|
||||
void fallingMonsterAnimation(cell *c, eMonster m, int id) {
|
||||
if(!mmspatial) return;
|
||||
fallanim& fa = fallanims[c];
|
||||
fa.t_mon = ticks;
|
||||
fa.m = m;
|
||||
fa.pid = id;
|
||||
// drawParticles(c, darkenedby(linf[c->land].color, 1), 4, 50);
|
||||
}
|
||||
|
||||
@ -4240,20 +4260,30 @@ void drawMarkers() {
|
||||
/* for(int i=0; i<12; i++) if(c->type == 5 && c->master == &dodecahedron[i])
|
||||
queuechr(xc, yc, sc, 4*vid.fsize, 'A'+i, iinf[itOrbDomination].color); */
|
||||
|
||||
IG(keycell) {
|
||||
queuechr(Gm0(keycell), 2*vid.fsize, 'X', 0x10101 * int(128 + 100 * sin(ticks / 150.)));
|
||||
queuestr(Gm0(keycell), vid.fsize, its(keycelldist), 0x10101 * int(128 - 100 * sin(ticks / 150.)));
|
||||
}
|
||||
|
||||
IG(pirateTreasureFound) {
|
||||
pirateCoords = Gm0(pirateTreasureFound);
|
||||
if(showPirateX) {
|
||||
queuechr(pirateCoords, 2*vid.fsize, 'X', 0x10100 * int(128 + 100 * sin(ticks / 150.)));
|
||||
if(numplayers() == 1 && cwt.c->master->alt)
|
||||
queuestr(pirateCoords, vid.fsize, its(-celldistAlt(cwt.c)), 0x10101 * int(128 - 100 * sin(ticks / 150.)));
|
||||
{
|
||||
using namespace yendor;
|
||||
if(yii < size(yi) && !yi[yii].found) {
|
||||
cell *keycell = NULL;
|
||||
int i;
|
||||
for(i=0; i<YDIST; i++)
|
||||
if(yi[yii].path[i]->cpdist <= sightrange) {
|
||||
keycell = yi[yii].path[i];
|
||||
break;
|
||||
}
|
||||
if(keycell) {
|
||||
for(; i<YDIST; i++) {
|
||||
cell *c = yi[yii].path[i];
|
||||
if(inscreenrange(c))
|
||||
keycell = c;
|
||||
}
|
||||
hyperpoint H = tC0(shmup::ggmatrix(keycell));
|
||||
queuechr(H, 2*vid.fsize, 'X', 0x10101 * int(128 + 100 * sin(ticks / 150.)));
|
||||
queuestr(H, vid.fsize, its(celldistance(cwt.c, yi[yii].key())), 0x10101 * int(128 - 100 * sin(ticks / 150.)));
|
||||
addauraspecial(H, iinf[itOrbYendor].color, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(lmouseover && vid.drawmousecircle && ok && DEFAULTCONTROL && MOBON) {
|
||||
queuecircleat(lmouseover, .8, darkena(lmouseover->cpdist > 1 ? 0x00FFFF : 0xFF0000, 0, 0xFF));
|
||||
}
|
||||
@ -4434,27 +4464,6 @@ void drawthemap() {
|
||||
minf[g.m].name = g.name;
|
||||
}
|
||||
|
||||
keycell = NULL;
|
||||
|
||||
pirateTreasureFound = pirateTreasureSeek;
|
||||
pirateTreasureSeek = NULL;
|
||||
straightDownSeek = NULL; downspin = 0;
|
||||
shmup::mousetarget = NULL;
|
||||
showPirateX = false;
|
||||
for(int i=0; i<numplayers(); i++) if(multi::playerActive(i))
|
||||
if(playerpos(i)->item == itCompass) showPirateX = true;
|
||||
|
||||
using namespace yendor;
|
||||
|
||||
if(yii < size(yi)) {
|
||||
if(!yi[yii].found)
|
||||
for(int i=0; i<YDIST; i++)
|
||||
if(yi[yii].path[i]->cpdist <= sightrange) {
|
||||
keycell = yi[yii].path[i];
|
||||
keycelldist = YDIST - i;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapeditor::autochoose) mapeditor::ew = mapeditor::ewsearch;
|
||||
mapeditor::ewsearch.dist = 1e30;
|
||||
modist = 1e20; mouseover = NULL;
|
||||
@ -4467,6 +4476,8 @@ void drawthemap() {
|
||||
multi::ccdist[i] = 1e20; multi::ccat[i] = NULL;
|
||||
}
|
||||
|
||||
straightDownSeek = NULL; downspin = 0;
|
||||
|
||||
#if ISMOBILE
|
||||
mouseovers = XLAT("No info about this...");
|
||||
#endif
|
||||
@ -4787,7 +4798,7 @@ void normalscreen() {
|
||||
cmode = sm::NORMAL | sm::DOTOUR | sm::CENTER;
|
||||
if(viewdists) cmode |= sm::SIDE;
|
||||
gamescreen(hiliteclick && mmmon ? 1 : 0); drawStats();
|
||||
if(nomenukey)
|
||||
if(nomenukey || ISMOBILE)
|
||||
;
|
||||
#if CAP_TOUR
|
||||
else if(tour::on)
|
||||
@ -4999,3 +5010,21 @@ void animateReplacement(cell *a, cell *b, int layer) {
|
||||
animateMovement(a, b, layer);
|
||||
animateMovement(&c1, a, layer);
|
||||
}
|
||||
|
||||
void drawBug(const cellwalker& cw, int col) {
|
||||
initquickqueue();
|
||||
transmatrix V = shmup::ggmatrix(cw.c);
|
||||
if(cw.spin) V = V * ddspin(cw.c, cw.spin, S42);
|
||||
queuepoly(V, shBugBody, col);
|
||||
quickqueue();
|
||||
}
|
||||
|
||||
cell *viewcenter() {
|
||||
if(euclid) return centerover;
|
||||
else return viewctr.h->c7;
|
||||
}
|
||||
|
||||
bool inscreenrange(cell *c) {
|
||||
return celldistance(viewcenter(), c) <= (euclid ? sightrange : purehepta ? 9 : 13);
|
||||
}
|
||||
|
||||
|
24
help.cpp
24
help.cpp
@ -28,11 +28,12 @@ string buildHelpText() {
|
||||
h += XLAT(" (press ESC for some hints about it).");
|
||||
h += "\n\n";
|
||||
|
||||
h += XLAT(
|
||||
"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"
|
||||
);
|
||||
if(!shmup::on && !hardcore)
|
||||
h += XLAT(
|
||||
"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"
|
||||
);
|
||||
|
||||
if(inv::on)
|
||||
h += XLAT(
|
||||
@ -56,10 +57,11 @@ string buildHelpText() {
|
||||
"numbers displayed to get their meanings.\n"
|
||||
);
|
||||
#else
|
||||
h += XLAT(
|
||||
"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 the main menu (configuration, special modes, etc.), ESC for the quest status.\n\n"
|
||||
);
|
||||
if(DEFAULTCONTROL)
|
||||
h += XLAT(
|
||||
"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 the main menu (configuration, special modes, etc.), ESC for the quest status.\n\n"
|
||||
);
|
||||
h += XLAT(
|
||||
"You can right click any element to get more information about it.\n\n"
|
||||
);
|
||||
@ -236,12 +238,12 @@ string generateHelpForItem(eItem it) {
|
||||
"and everywhere after you collect 100.");
|
||||
}
|
||||
|
||||
if(it == itBone || it == itGreenStone) {
|
||||
/* if(it == itBone || it == itGreenStone) {
|
||||
help += XLAT(
|
||||
"\n\nIn the Orb Strategy Mode, dead orbs are available once you collect "
|
||||
"10 Necromancer Totems in the Graveyard."
|
||||
);
|
||||
}
|
||||
} */
|
||||
|
||||
if(it == itFeather || it == itOrbSafety) {
|
||||
help += XLAT(
|
||||
|
39
hud.cpp
39
hud.cpp
@ -50,14 +50,27 @@ const int glyphs = ittypes + motypes;
|
||||
|
||||
int gfirsttime[glyphs], glasttime[glyphs], gcopy[glyphs], ikland[glyphs];
|
||||
int glyphorder[glyphs];
|
||||
int glyphphase[glyphs];
|
||||
int glyph_lastticks;
|
||||
|
||||
void updatesort() {
|
||||
for(int i=0; i<glyphs; i++) {
|
||||
if(ikmerge(i) && gfirsttime[i] == 0)
|
||||
int ik = ikmerge(i);
|
||||
if(ik && gfirsttime[i] == 0)
|
||||
gfirsttime[i] = ticks;
|
||||
if(ikmerge(i) != gcopy[i])
|
||||
gcopy[i] = items[i], glasttime[i] = ticks;
|
||||
}
|
||||
if(ik != gcopy[i])
|
||||
gcopy[i] = ik, glasttime[i] = ticks;
|
||||
int& gp = glyphphase[i];
|
||||
if(ticks <= glasttime[i]+500)
|
||||
gp += (ticks - glyph_lastticks);
|
||||
else if((gp % 500) && i >= ittypes) {
|
||||
int a = gp;
|
||||
gp += (ticks - glyph_lastticks);
|
||||
if(a/500 != gp/500)
|
||||
gp = gp/500*500;
|
||||
}
|
||||
}
|
||||
glyph_lastticks = ticks;
|
||||
}
|
||||
|
||||
void preparesort() {
|
||||
@ -148,33 +161,39 @@ bool displayglyph(int cx, int cy, int buttonsize, char glyph, int color, int qty
|
||||
int glsize = buttonsize;
|
||||
if(glyph == '%' || glyph == 'M' || glyph == 'W') glsize = glsize*4/5;
|
||||
|
||||
int d = ticks - glasttime[id];
|
||||
double zoom = (d <= 250 && d >= 0) ? 1.25 - .001 * d : 1;
|
||||
glsize = int(glsize * zoom);
|
||||
|
||||
if(graphglyph()) {
|
||||
initquickqueue();
|
||||
if(id >= ittypes) {
|
||||
eMonster m = eMonster(id - ittypes);
|
||||
int bsize = buttonsize * 2/3;
|
||||
double bsize = buttonsize * 2/3;
|
||||
if(m == moKrakenH) bsize /= 3;
|
||||
if(m == moKrakenT || m == moDragonTail) bsize /= 2;
|
||||
if(m == moSlime) bsize = (2*bsize+1)/3;
|
||||
transmatrix V = atscreenpos(cx+buttonsize/2, cy, bsize);
|
||||
transmatrix V = atscreenpos(cx+buttonsize/2, cy, bsize*zoom);
|
||||
int mcol = color;
|
||||
mcol -= (color & 0xFCFCFC) >> 2;
|
||||
drawMonsterType(m, NULL, V, mcol, 0);
|
||||
drawMonsterType(m, NULL, V, mcol, glyphphase[id]/500.0);
|
||||
}
|
||||
else {
|
||||
eItem it = eItem(id);
|
||||
int bsize = buttonsize / 2;
|
||||
double bsize = buttonsize / 2;
|
||||
if(glyph =='*') bsize *= 2;
|
||||
if(glyph == '$') bsize = (bsize*5+2)/3;
|
||||
if(glyph == 'o') bsize = (bsize*3+1)/2;
|
||||
if(glyph == 't') bsize = bsize*5/2;
|
||||
if(it == itWarning) bsize *= 2;
|
||||
if(it == itBombEgg || it == itTrollEgg || it == itDodeca) bsize = bsize*3/2;
|
||||
transmatrix V = atscreenpos(cx+buttonsize/2, cy, bsize);
|
||||
int icol = color;
|
||||
icol -= (color & 0xFCFCFC) >> 2;
|
||||
int ic = itemclass(it);
|
||||
drawItemType(it, NULL, V, icol, (ic == IC_ORB || ic == IC_NAI) ? ticks*2 : ((glyph == 't' && qty%5) || it == itOrbYendor) ? ticks/2 : 0, false);
|
||||
bsize = bsize * zoom;
|
||||
transmatrix V = atscreenpos(cx+buttonsize/2, cy, bsize);
|
||||
drawItemType(it, NULL, V, icol, (ic == IC_ORB || ic == IC_NAI) ? ticks*2 : ((glyph == 't' && qty%5) || it == itOrbYendor) ? ticks/2 :
|
||||
glyphphase[id] * 2, false);
|
||||
}
|
||||
quickqueue();
|
||||
}
|
||||
|
25
hyper.cpp
25
hyper.cpp
@ -117,7 +117,7 @@ int arg::readCommon() {
|
||||
else if(argis("-load")) { PHASE(3); shift(); mapstream::loadMap(loadlevel); }
|
||||
#endif
|
||||
else if(argis("-canvas")) {
|
||||
firstland = euclidland = laCanvas;
|
||||
firstland = specialland = laCanvas;
|
||||
shift();
|
||||
if(args()[1] == 0) mapeditor::whichCanvas = args()[0];
|
||||
else mapeditor::canvasback = strtol(args(), NULL, 16);
|
||||
@ -133,9 +133,11 @@ int arg::readCommon() {
|
||||
}
|
||||
else if(argis("-W2")) {
|
||||
shift(); cheatdest = readland(args()); autocheat = true;
|
||||
showstartmenu = false;
|
||||
}
|
||||
else if(argis("-W")) {
|
||||
shift(); firstland = euclidland = readland(args());
|
||||
shift(); firstland = specialland = readland(args());
|
||||
showstartmenu = false;
|
||||
}
|
||||
else if(argis("-I")) {
|
||||
PHASE(3) cheater++; timerghost = false;
|
||||
@ -186,9 +188,9 @@ int arg::readCommon() {
|
||||
else if(argis("-mm")) { PHASEFROM(2); vid.monmode = argi(); }
|
||||
|
||||
#define TOGGLE(x, param, act) \
|
||||
else if(args()[0] == '-' && args()[1] == x && !args()[2]) { if(curphase == 3) {act;} else {PHASE(2); param = !param;} } \
|
||||
else if(args()[0] == '-' && args()[1] == x && args()[2] == '1') { if(curphase == 3 && !param) {act;} else {PHASE(2); param = true;} } \
|
||||
else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { if(curphase == 3 && param) {act;} else {PHASE(2); param = false;} }
|
||||
else if(args()[0] == '-' && args()[1] == x && !args()[2]) { showstartmenu = false; if(curphase == 3) {act;} else {PHASE(2); param = !param;} } \
|
||||
else if(args()[0] == '-' && args()[1] == x && args()[2] == '1') { showstartmenu = false; if(curphase == 3 && !param) {act;} else {PHASE(2); param = true;} } \
|
||||
else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu = false; if(curphase == 3 && param) {act;} else {PHASE(2); param = false;} }
|
||||
|
||||
TOGGLE('o', vid.usingGL, switchGL())
|
||||
TOGGLE('C', chaosmode, restartGame('C'))
|
||||
@ -198,7 +200,18 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { if(curphase ==
|
||||
TOGGLE('S', shmup::on, restartGame('s'))
|
||||
TOGGLE('H', hardcore, switchHardcore())
|
||||
TOGGLE('R', randomPatternsMode, restartGame('r'))
|
||||
TOGGLE('i', inv::on, restartGame('i'))
|
||||
|
||||
else if(argis("-peace")) {
|
||||
peace::otherpuzzles = true;
|
||||
if(curphase == 3) restartGame('P');
|
||||
else peace::on = true;
|
||||
}
|
||||
else if(argis("-pmem")) {
|
||||
peace::otherpuzzles = false;
|
||||
if(curphase == 3) restartGame('P');
|
||||
else peace::on = true;
|
||||
}
|
||||
else if(argis("-geo")) {
|
||||
if(curphase == 3) {
|
||||
shift(); targetgeometry = (eGeometry) argi();
|
||||
@ -413,6 +426,8 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
initAll();
|
||||
arg::read(3);
|
||||
if(showstartmenu)
|
||||
pushScreen(showStartMenu);
|
||||
mainloop();
|
||||
finishAll();
|
||||
profile_info();
|
||||
|
27
hyper.h
27
hyper.h
@ -158,6 +158,7 @@ void loadcs(FILE *f, charstyle& cs, int vernum);
|
||||
namespace multi {
|
||||
|
||||
extern bool shmupcfg;
|
||||
extern bool alwaysuse;
|
||||
void recall();
|
||||
extern cell *origpos[MAXPLAYER], *origtarget[MAXPLAYER];
|
||||
extern int players;
|
||||
@ -345,6 +346,7 @@ struct videopar {
|
||||
#define AA_LINEWIDTH 16
|
||||
#define AA_FONT 32
|
||||
#define AA_MULTI 64
|
||||
#define AA_MULTI16 128 // not configurable
|
||||
ld linewidth;
|
||||
|
||||
int joyvalue, joyvalue2, joypanthreshold;
|
||||
@ -361,6 +363,8 @@ struct videopar {
|
||||
|
||||
int steamscore;
|
||||
bool drawmousecircle; // draw the circle around the mouse
|
||||
bool skipstart; // skip the start menu
|
||||
int quickmouse; // quick mouse on the map
|
||||
};
|
||||
|
||||
extern videopar vid;
|
||||
@ -544,7 +548,7 @@ extern int sval;
|
||||
|
||||
extern int items[ittypes], hiitems[MODECODES][ittypes], kills[motypes], explore[10], exploreland[10][landtypes], landcount[landtypes];
|
||||
|
||||
extern eLand firstland, euclidland;
|
||||
extern eLand firstland, specialland;
|
||||
bool pseudohept(cell *c);
|
||||
bool pureHardcore();
|
||||
extern int cheater;
|
||||
@ -797,7 +801,7 @@ extern bool timerghost;
|
||||
|
||||
namespace dialog {
|
||||
|
||||
enum tDialogItem {diTitle, diItem, diBreak, diHelp, diInfo, diSlider};
|
||||
enum tDialogItem {diTitle, diItem, diBreak, diHelp, diInfo, diSlider, diBigItem};
|
||||
|
||||
struct item {
|
||||
tDialogItem type;
|
||||
@ -907,7 +911,7 @@ void commitAnimations(int layer);
|
||||
|
||||
void animateReplacement(cell *a, cell *b, int layer);
|
||||
void fallingFloorAnimation(cell *c, eWall w = waNone, eMonster m = moNone);
|
||||
void fallingMonsterAnimation(cell *c, eMonster m);
|
||||
void fallingMonsterAnimation(cell *c, eMonster m, int id = multi::cpid);
|
||||
|
||||
// ranks:
|
||||
enum PPR {
|
||||
@ -1288,6 +1292,8 @@ void pushThumper(cell *th, cell *cto);
|
||||
template<class T> T pick(T x, T y) { return hrand(2) ? x : y; }
|
||||
template<class T> T pick(T x, T y, T z) { switch(hrand(3)) { case 0: return x; case 1: return y; case 2: return z; } return x; }
|
||||
template<class T> T pick(T x, T y, T z, T v) { switch(hrand(4)) { case 0: return x; case 1: return y; case 2: return z; case 3: return v; } return x; }
|
||||
template<class T, class... U> bool among(T x, T y) { return x == y; }
|
||||
template<class T, class... U> bool among(T x, T y, U... u) { return x==y || among(x,u...); }
|
||||
|
||||
eLand getNewSealand(eLand old);
|
||||
bool createOnSea(eLand old);
|
||||
@ -1356,7 +1362,7 @@ extern hookset<eLand(eLand)> *hooks_nextland;
|
||||
|
||||
extern ld shiftmul;
|
||||
void initcs(charstyle &cs);
|
||||
charstyle& getcs();
|
||||
charstyle& getcs(int id = multi::cpid);
|
||||
|
||||
struct msginfo {
|
||||
int stamp;
|
||||
@ -1470,7 +1476,7 @@ bool needConfirmation();
|
||||
extern const char* geometrynames_short[gGUARD];
|
||||
|
||||
namespace mirror {
|
||||
cellwalker reflect(cellwalker cw, bool debug = false);
|
||||
cellwalker reflect(const cellwalker& cw);
|
||||
}
|
||||
|
||||
bool inmirror(eLand l);
|
||||
@ -1508,3 +1514,14 @@ int gl_width(int size, const char *s);
|
||||
#ifdef ISMOBILE
|
||||
extern int andmode;
|
||||
#endif
|
||||
|
||||
void addaura(const hyperpoint& h, int col, int fd);
|
||||
void addauraspecial(const hyperpoint& h, int col, int dir);
|
||||
|
||||
void drawBug(const cellwalker& cw, int col);
|
||||
|
||||
void mainloop();
|
||||
extern bool showstartmenu;
|
||||
void selectLanguageScreen();
|
||||
|
||||
bool inscreenrange(cell *c);
|
||||
|
10
hyper.rc
10
hyper.rc
@ -1,8 +1,8 @@
|
||||
id ICON "hr-icon.ico"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 10,0,0,3
|
||||
PRODUCTVERSION 10,0,0,3
|
||||
FILEVERSION 10,0,0,7
|
||||
PRODUCTVERSION 10,0,0,7
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
@ -10,12 +10,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Zeno Rogue"
|
||||
VALUE "FileDescription", "A roguelike in non-euclidean space"
|
||||
VALUE "FileVersion", "A10.0b"
|
||||
VALUE "InternalName", "hyper"
|
||||
VALUE "FileVersion", "A10.0g"
|
||||
VALUE "InternalName", "hype"
|
||||
VALUE "LegalCopyright", "Zeno Rogue"
|
||||
VALUE "OriginalFilename", "hyper.exe"
|
||||
VALUE "ProductName", "HyperRogue"
|
||||
VALUE "ProductVersion", "10.0c"
|
||||
VALUE "ProductVersion", "10.0g"
|
||||
END
|
||||
END
|
||||
|
||||
|
18
init.cpp
18
init.cpp
@ -1,6 +1,6 @@
|
||||
#define VER "10.0e"
|
||||
#define VERNUM 10005
|
||||
#define VERNUM_HEX 0xA005
|
||||
#define VER "10.0g"
|
||||
#define VERNUM 10007
|
||||
#define VERNUM_HEX 0xA007
|
||||
|
||||
#define GEN_M 0
|
||||
#define GEN_F 1
|
||||
@ -93,7 +93,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef CAP_EDIT
|
||||
#define CAP_EDIT (!ISMOBWEB && !ISMINI)
|
||||
#define CAP_EDIT (!ISWEB && !ISMINI)
|
||||
#endif
|
||||
|
||||
#ifndef CAP_MODEL
|
||||
@ -330,6 +330,7 @@ const char *loadlevel = NULL;
|
||||
bool inv::on;
|
||||
#endif
|
||||
#include "system.cpp"
|
||||
#include "debug.cpp"
|
||||
#include "geometry.cpp"
|
||||
#include "polygons.cpp"
|
||||
#include "mapeditor.cpp"
|
||||
@ -368,6 +369,7 @@ bool fixseed = false;
|
||||
int startseed = 0;
|
||||
|
||||
void initAll() {
|
||||
showstartmenu = true;
|
||||
ca::init();
|
||||
arg::read(1);
|
||||
srand(time(NULL));
|
||||
@ -552,7 +554,13 @@ void handleclick(MOBPAR_FORMAL) {
|
||||
|
||||
if(andmode >= 10) andmode -= 10;
|
||||
|
||||
if(andmode == 3) pushScreen(showMainMenu), andmode = 0;
|
||||
if(andmode == 3) {
|
||||
if(tour::on)
|
||||
showMissionScreen();
|
||||
else
|
||||
pushScreen(showMainMenu);
|
||||
andmode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int touchedAt;
|
||||
|
116
inventory.cpp
116
inventory.cpp
@ -70,15 +70,16 @@ namespace inv {
|
||||
}
|
||||
|
||||
void gainOrbs(eItem it, eItem o) {
|
||||
auto& nx = next[o == itHyperstone ? o : it];
|
||||
int qty = items[it];
|
||||
if(it == itHolyGrail) {
|
||||
remaining[itOrbIllusion] += qty;
|
||||
next[it] = {qty+1, qty+1, qty+1};
|
||||
nx = {qty+1, qty+1, qty+1};
|
||||
}
|
||||
else {
|
||||
bool nextfound = false;
|
||||
if(qty >= 10) remaining[o]++;
|
||||
else next[it] = {10,10,10}, nextfound = true;
|
||||
else nx = {10,10,10}, nextfound = true;
|
||||
int last = 10;
|
||||
for(int k=0; k<30 || !nextfound; k++) {
|
||||
int maxstep = 15 + 5 * k;
|
||||
@ -94,17 +95,47 @@ namespace inv {
|
||||
else
|
||||
xnext = last + 1 + irand(maxstep);
|
||||
if(xnext > qty && !nextfound)
|
||||
next[it] = { last+1, xnext, last + maxstep }, nextfound = true;
|
||||
nx = { last+1, xnext, last + maxstep }, nextfound = true;
|
||||
if(xnext <= qty) remaining[o]++;
|
||||
last = xnext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int nextp2(int i) {
|
||||
int z = 1;
|
||||
while(z <= i) z <<= 1;
|
||||
return z;
|
||||
}
|
||||
|
||||
void gainMirrors(int qtl) {
|
||||
while(qtl > 0) qtl >>= 1, remaining[itOrbMirror]++;
|
||||
}
|
||||
|
||||
|
||||
vector<eItem> offensiveOrbs = {
|
||||
itOrbFlash, itOrbLightning, itOrbPsi, itOrbThorns,
|
||||
itOrbFreedom, itOrbSword, itOrbSword2,
|
||||
itOrbHorns, itOrbDragon, itOrbStunning
|
||||
};
|
||||
|
||||
vector<eItem> elementalOrbs = {itOrbFire, itOrbWater, itOrbDigging, itOrbAir};
|
||||
|
||||
vector<eItem> demonicOrbs = {itOrbFire, itOrbHorns, itOrbSummon};
|
||||
|
||||
bool isIn(eItem o, vector<eItem>& l) {
|
||||
for(auto it: l) if(it == o) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void gainRandomOrbs(vector<eItem> orblist, eItem which, int each, int reduce) {
|
||||
const int qoff = size(orblist);
|
||||
for(int i=1; i<qoff; i++) swap(orblist[i], orblist[irand(1+i)]);
|
||||
for(int i=0; i<20; i++) {
|
||||
if((i+1)*each <= items[which] - reduce)
|
||||
remaining[orblist[i%qoff]]++;
|
||||
}
|
||||
}
|
||||
|
||||
void compute() {
|
||||
for(int i=0; i<ittypes; i++) remaining[i] = -usedup[i];
|
||||
for(int i=0; i<ittypes; i++) if(usedup[i] >= TESTMIRRORED) remaining[i] += MIRRORED;
|
||||
@ -148,24 +179,18 @@ namespace inv {
|
||||
}
|
||||
}
|
||||
|
||||
vector<eItem> offensiveOrbs = {
|
||||
itOrbFlash, itOrbLightning, itOrbPsi, itOrbThorns,
|
||||
itOrbFreedom, itOrbSword, itOrbSword2,
|
||||
itOrbHorns, itOrbDragon, itOrbStunning
|
||||
};
|
||||
const int qoff = size(offensiveOrbs);
|
||||
for(int i=1; i<qoff; i++) swap(offensiveOrbs[i], offensiveOrbs[irand(1+i)]);
|
||||
for(int i=0; (i+1)*25 <= items[itBone]; i++)
|
||||
remaining[offensiveOrbs[i%qoff]]++;
|
||||
gainRandomOrbs(offensiveOrbs, itBone, 25, 0);
|
||||
gainRandomOrbs(elementalOrbs, itElemental, 20, 0);
|
||||
gainRandomOrbs(demonicOrbs, itHell, 20, 100);
|
||||
|
||||
if(items[itOrbLove] && !items[itSavedPrincess]) items[itSavedPrincess] = 1;
|
||||
|
||||
int& r = remaining[itGreenStone];
|
||||
|
||||
if(items[itBone] >= 10) {
|
||||
if(items[itBone] >= 0) {
|
||||
for(int i=0; i<ittypes; i++) if(i != itGreenStone) {
|
||||
r += usedup[i];
|
||||
if(usedup[i] >= TESTMIRRORED) r -= MIRRORED;
|
||||
if(usedup[i] >= TESTMIRRORED) r -= (MIRRORED - mirrorqty(eItem(i)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,6 +239,10 @@ namespace inv {
|
||||
"several quests and lands "
|
||||
"give you extremely powerful Orbs of the Mirror.\n";
|
||||
|
||||
string extraline(eItem it, string s) {
|
||||
return " "+XLAT1(iinf[it].name) + " ("+s+")";
|
||||
}
|
||||
|
||||
void show() {
|
||||
|
||||
gamescreen(2);
|
||||
@ -245,8 +274,8 @@ namespace inv {
|
||||
dialog::addSelItem(XLAT1(iinf[o].name), its(remaining[i]), c);
|
||||
else {
|
||||
auto pos = orbcoord[oc++];
|
||||
ld px = vid.xres/2 + 2*rad*pos.first + rad*pos.second;
|
||||
ld py = vid.yres/2 + pos.second * rad3;
|
||||
ld px = vid.xcenter + 2*rad*pos.first + rad*pos.second;
|
||||
ld py = vid.ycenter + pos.second * rad3;
|
||||
int icol = iinf[o].color;
|
||||
if(!remaining[i]) icol = gradient(icol, 0, 0, .5, 1);
|
||||
bool gg = graphglyph();
|
||||
@ -283,7 +312,6 @@ namespace inv {
|
||||
which = orbmap[getcstat];
|
||||
}
|
||||
else {
|
||||
|
||||
if(which == itNone) {
|
||||
displaystr(vid.xres/2, vid.fsize*2, 2, vid.fsize*2, XLAT("Which orb to use?"), 0xC0C0C0, 8);
|
||||
}
|
||||
@ -301,13 +329,43 @@ namespace inv {
|
||||
s += XLAT(" (next at %1)", its(next[t].min));
|
||||
else
|
||||
s += XLAT(" (next at %1 to %2)", its(next[t].min), its(next[t].max));
|
||||
|
||||
displaystr(vid.xres/2, vid.fsize*4, 2, vid.fsize, s, icol, 8);
|
||||
|
||||
|
||||
string extras = "";
|
||||
for(int k=0; k<ORBLINES; k++) {
|
||||
auto oi = orbinfos[k];
|
||||
if(oi.gchance || oi.orb != which) continue;
|
||||
eItem it = treasureType(oi.l);
|
||||
extras += extraline(it, "10");
|
||||
}
|
||||
|
||||
if(which == itOrbMirror) {
|
||||
extras += extraline(itOrbYendor, its(nextp2(items[itOrbYendor])));
|
||||
extras += extraline(itHolyGrail, its(nextp2(items[itHolyGrail])));
|
||||
auto& nx = next[itHyperstone];
|
||||
extras += extraline(itHyperstone, its(nx.min));
|
||||
}
|
||||
if(isIn(which, offensiveOrbs)) extras += extraline(itBone, its(items[itBone]/25*25+25) + "?");
|
||||
if(isIn(which, elementalOrbs)) extras += extraline(itElemental, its(items[itBone]/20*20+20) + "?");
|
||||
if(isIn(which, demonicOrbs)) extras += extraline(itHell, its(max(125, items[itHell]/25*25+25)) + "?");
|
||||
|
||||
if(extras != "")
|
||||
displaystr(vid.xres/2, vid.fsize*5, 2, vid.fsize, XLAT("Extras:")+extras, icol, 8);
|
||||
}
|
||||
if(remaining[which] != 1)
|
||||
displaystr(vid.xres/2, vid.fsize*5, 2, vid.fsize, XLAT("Number of uses left: %1", its(remaining[which])), icol, 8);
|
||||
|
||||
if(remaining[which] != 1 || usedup[which]) {
|
||||
string s = XLAT("Number of uses left: %1", its(remaining[which]));
|
||||
int us = usedup[which];
|
||||
if(us >= TESTMIRRORED) s += XLAT(" (mirrored)"), us = us - MIRRORED + mirrorqty(which);
|
||||
if(us) s += XLAT(" (used %1 times)", its(us));
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*6, 2, vid.fsize, s, icol, 8);
|
||||
}
|
||||
|
||||
#if ISMOBILE==0
|
||||
string hot = XLAT1("Hotkey: "); hot += getcstat;
|
||||
displaystr(vid.xres/2, vid.fsize*6, 2, vid.fsize, hot, icol, 8);
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*5, 2, vid.fsize, hot, icol, 8);
|
||||
#endif
|
||||
|
||||
eOrbLandRelation olr = getOLR(oi.orb, getPrizeLand());
|
||||
@ -330,7 +388,7 @@ namespace inv {
|
||||
|
||||
if(orbmap.count(uni)) {
|
||||
eItem orb = orbmap[uni];
|
||||
if(!remaining[orb]) ;
|
||||
if(remaining[orb] <= 0) ;
|
||||
else if(orb == itOrbMirror) {
|
||||
mirroring = !mirroring;
|
||||
// an amusing message
|
||||
@ -341,21 +399,20 @@ namespace inv {
|
||||
forCellEx(c2, cwt.c) if(c2->wall == waMirror || c2->wall == waCloud || c2->wall == waMirrorWall)
|
||||
next = true;
|
||||
if(!next) {
|
||||
addMessage("You need to stand next to a magic mirror or cloud to use %the1.", itOrbMirror);
|
||||
addMessage(XLAT("You need to stand next to a magic mirror or cloud to use %the1.", itOrbMirror));
|
||||
mirroring = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mirroring) {
|
||||
if(usedup[orb] >= TESTMIRRORED) {
|
||||
addMessage("Each orb type can be mirrored only once.");
|
||||
addMessage(XLAT("Each orb type can be mirrored only once."));
|
||||
mirroring = false;
|
||||
}
|
||||
else if(remaining[orb]) {
|
||||
else if(remaining[orb] > 0) {
|
||||
usedup[itOrbMirror]++;
|
||||
usedup[orb] += MIRRORED;
|
||||
usedup[orb] -= mirrorqty(orb);
|
||||
usedup[itGreenStone]--;
|
||||
addMessage(XLAT("You mirror %the1.", orb));
|
||||
mirroring = false;
|
||||
}
|
||||
@ -380,7 +437,10 @@ namespace inv {
|
||||
else if(uni == '1') plain = !plain;
|
||||
else if(sym == SDLK_F1)
|
||||
gotoHelp(which ? generateHelpForItem(which) : NODESCYET);
|
||||
else if(doexiton(sym, uni)) popScreen();
|
||||
else if(doexiton(sym, uni)) {
|
||||
if(mirroring) mirroring = false;
|
||||
popScreen();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
122
landgen.cpp
122
landgen.cpp
@ -37,7 +37,7 @@ bool buildBarrierNowall(cell *c, eLand l2, bool force = false);
|
||||
|
||||
bool safety = false;
|
||||
|
||||
eLand firstland = laIce, euclidland = laIce;
|
||||
eLand firstland = laIce, specialland = laIce;
|
||||
|
||||
bool timerghost = true;
|
||||
eLand lastland;
|
||||
@ -1000,10 +1000,10 @@ bool grailWasFound(cell *c) {
|
||||
}
|
||||
|
||||
int euclidAlt(short x, short y) {
|
||||
if(euclidland == laTemple || euclidland == laClearing) {
|
||||
if(specialland == laTemple || specialland == laClearing) {
|
||||
return max(int(x), x+y);
|
||||
}
|
||||
else if(euclidland == laCaribbean || euclidland == laWhirlpool || euclidland == laMountain) {
|
||||
else if(specialland == laCaribbean || specialland == laWhirlpool || specialland == laMountain) {
|
||||
return
|
||||
min(
|
||||
min(max(int(-x), -x-y) + 3,
|
||||
@ -1011,7 +1011,7 @@ int euclidAlt(short x, short y) {
|
||||
max(int(x), int(-y)) + 3
|
||||
);
|
||||
}
|
||||
else if(euclidland == laPrincessQuest)
|
||||
else if(specialland == laPrincessQuest)
|
||||
return eudist(x-EPX, y-EPY);
|
||||
else return eudist(x-20, y-10);
|
||||
}
|
||||
@ -1197,42 +1197,6 @@ void describeCell(cell *c) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#ifdef BACKTRACE
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
void raiseBuggyGeneration(cell *c, const char *s) {
|
||||
|
||||
printf("procgen error (%p): %s\n", c, s);
|
||||
|
||||
if(!errorReported) {
|
||||
addMessage(string("something strange happened in: ") + s);
|
||||
errorReported = true;
|
||||
}
|
||||
// return;
|
||||
|
||||
#ifdef DEBUG_LANDGEN
|
||||
describeCell(c);
|
||||
for(int i=0; i<c->type; i++) describeCell(c->mov[i]);
|
||||
|
||||
buggyGeneration = true; buggycells.push_back(c);
|
||||
|
||||
#else
|
||||
c->item = itBuggy;
|
||||
#endif
|
||||
|
||||
#ifdef BACKTRACE
|
||||
void *array[1000];
|
||||
size_t size;
|
||||
|
||||
// get void*'s for all entries on the stack
|
||||
size = backtrace(array, 1000);
|
||||
|
||||
// print out all the frames to stderr
|
||||
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setland(cell *c, eLand l) {
|
||||
if(c->land != l) {
|
||||
c->landparam = 0;
|
||||
@ -1691,7 +1655,7 @@ bool noChaos(eLand l) {
|
||||
return
|
||||
isCrossroads(l) || isCyclic(l) || isHaunted(l) ||
|
||||
l == laCaribbean || isGravityLand(l) || l == laPrincessQuest ||
|
||||
l == laPrairie;
|
||||
l == laPrairie || l == laHalloween;
|
||||
}
|
||||
|
||||
eLand getNewSealand(eLand old) {
|
||||
@ -1819,7 +1783,7 @@ eLand getNewLand(eLand old) {
|
||||
tab[cnt++] = laLivefjord;
|
||||
tab[cnt++] = laMinefield;
|
||||
tab[cnt++] = laPalace;
|
||||
if(old == laDragon) LIKELY tab[cnt++] = laReptile;
|
||||
if(old == laDragon && items[itElixir] >= U10) LIKELY tab[cnt++] = laReptile;
|
||||
if(kills[moVizier]) tab[cnt++] = laEmerald;
|
||||
if(items[itFeather] >= U10) tab[cnt++] = laZebra;
|
||||
tab[cnt++] = laWarpCoast;
|
||||
@ -1961,7 +1925,7 @@ bool notDippingForExtra(eItem i, eItem x) {
|
||||
eLand euland[65536];
|
||||
|
||||
eLand switchable(eLand nearland, eLand farland, eucoord c) {
|
||||
if(euclidland == laCrossroads4) {
|
||||
if(specialland == laCrossroads4) {
|
||||
if(hrand(15) == 0)
|
||||
return getNewLand(nearland);
|
||||
return nearland;
|
||||
@ -1984,7 +1948,7 @@ eLand switchable(eLand nearland, eLand farland, eucoord c) {
|
||||
eLand getEuclidLand(eucoord c) {
|
||||
if(euland[c]) return euland[c];
|
||||
if(c == 0 || c == eucoord(-1) || c == 1)
|
||||
return euland[c] = euclidland;
|
||||
return euland[c] = specialland;
|
||||
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
|
||||
@ -2479,6 +2443,8 @@ int coastval(cell *c, eLand base) {
|
||||
}
|
||||
else if(base == laMirrored) {
|
||||
if(!inmirror(c)) return 0;
|
||||
if(!c->landparam) return UNKNOWN;
|
||||
return c->landparam & 255;
|
||||
}
|
||||
else {
|
||||
if(c->land == laOceanWall || c->land == laCaribbean || c->land == laWhirlpool ||
|
||||
@ -2846,10 +2812,30 @@ int getHauntedDepth(cell *c) {
|
||||
return -100;
|
||||
}
|
||||
|
||||
const int NOCOMPASS = 1000000;
|
||||
|
||||
int compassDist(cell *c) {
|
||||
if(c->master->alt) return celldistAlt(c);
|
||||
if(isHaunted(c->land) || c->land == laGraveyard) return getHauntedDepth(c);
|
||||
return 500;
|
||||
return NOCOMPASS;
|
||||
}
|
||||
|
||||
cell *findcompass(cell *c) {
|
||||
int d = compassDist(c);
|
||||
if(d == NOCOMPASS) return NULL;
|
||||
|
||||
while(inscreenrange(c)) {
|
||||
generateAlts(c->master);
|
||||
forCellEx(c2, c) if(compassDist(c2) < d) {
|
||||
c = c2;
|
||||
d = compassDist(c2);
|
||||
goto nextk;
|
||||
}
|
||||
break;
|
||||
nextk: ;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int towerval(cell *c, cellfunction* cf) {
|
||||
@ -2930,9 +2916,9 @@ bool buildBarrierNowall(cell *c, eLand l2, bool force) {
|
||||
void setLandQuotient(cell *c) {
|
||||
int fv = zebra40(c);
|
||||
if(fv/4 == 4 || fv/4 == 6 || fv/4 == 5 || fv/4 == 10) fv ^= 2;
|
||||
if(euclidland == laWarpCoast)
|
||||
if(specialland == laWarpCoast)
|
||||
if(fv%4==0 || fv%4 == 2) setland(c, laWarpSea);
|
||||
if(euclidland == laElementalWall)
|
||||
if(specialland == laElementalWall)
|
||||
setland(c, eLand(laEFire + (fv%4)));
|
||||
}
|
||||
|
||||
@ -2945,9 +2931,9 @@ bool quickfind(eLand l) {
|
||||
}
|
||||
|
||||
void setLandSphere(cell *c) {
|
||||
if(euclidland == laWarpCoast)
|
||||
if(specialland == laWarpCoast)
|
||||
setland(c, getHemisphere(c, 0) > 0 ? laWarpCoast : laWarpSea);
|
||||
if(euclidland == laElementalWall) {
|
||||
if(specialland == laElementalWall) {
|
||||
int x = getHemisphere(c, 1);
|
||||
int y = getHemisphere(c, 2);
|
||||
if(x > 0 && y > 0) setland(c, laEFire);
|
||||
@ -2965,34 +2951,34 @@ void setLandSphere(cell *c) {
|
||||
if(c->land == laElementalWall && c->type != 6)
|
||||
c->wall = getElementalWall(hrand(2) ? c->barleft : c->barright);
|
||||
}
|
||||
if(euclidland == laCrossroads || euclidland == laCrossroads2 || euclidland == laCrossroads3) {
|
||||
if(specialland == laCrossroads || specialland == laCrossroads2 || specialland == laCrossroads3) {
|
||||
int x = getHemisphere(c, 1);
|
||||
if(x == 0 || (euclidland == laCrossroads3 && getHemisphere(c, 2) == 0))
|
||||
if(x == 0 || (specialland == laCrossroads3 && getHemisphere(c, 2) == 0))
|
||||
setland(c, laBarrier), c->wall = waBarrier;
|
||||
else setland(c, euclidland);
|
||||
if(euclidland == laCrossroads3 && c->type != 6 && c->master->fiftyval == 1)
|
||||
else setland(c, specialland);
|
||||
if(specialland == laCrossroads3 && c->type != 6 && c->master->fiftyval == 1)
|
||||
c->wall = waBigTree;
|
||||
}
|
||||
}
|
||||
|
||||
void setLandEuclid(cell *c) {
|
||||
setland(c, euclidland);
|
||||
if(euclidland == laCrossroads) {
|
||||
setland(c, specialland);
|
||||
if(specialland == laCrossroads) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
setland(c, getEuclidLand(y+2*x));
|
||||
}
|
||||
if(euclidland == laCrossroads4) {
|
||||
if(specialland == laCrossroads4) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
c->land = getEuclidLand(y);
|
||||
}
|
||||
if(euclidland == laWhirlpool) {
|
||||
if(specialland == laWhirlpool) {
|
||||
c->land = laOcean;
|
||||
c->landparam = 99;
|
||||
}
|
||||
if(euclidland == laPrincessQuest) setland(c, laPalace);
|
||||
if(euclidland == laOcean) {
|
||||
if(specialland == laPrincessQuest) setland(c, laPalace);
|
||||
if(specialland == laOcean) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
int y0 = y; if(y>50000) y0 -= 65536; y0 += 10;
|
||||
@ -3001,7 +2987,7 @@ void setLandEuclid(cell *c) {
|
||||
else if(y0<0) setland(c, laRlyeh);
|
||||
else c->landparam = y0;
|
||||
}
|
||||
if(euclidland == laIvoryTower || euclidland == laDungeon) {
|
||||
if(specialland == laIvoryTower || specialland == laDungeon) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
int y0 = y; if(y>50000) y0 -= 65536; y0 = -y0; y0 -= 5;
|
||||
@ -3012,7 +2998,7 @@ void setLandEuclid(cell *c) {
|
||||
c->landparam = y0;
|
||||
}
|
||||
}
|
||||
if(euclidland == laElementalWall) {
|
||||
if(specialland == laElementalWall) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
int y0 = y; if(y>32768) y0 -= 65536;
|
||||
@ -3041,7 +3027,7 @@ void setLandEuclid(cell *c) {
|
||||
setland(c, laElementalWall);
|
||||
}
|
||||
}
|
||||
if(euclidland == laCrossroads3) {
|
||||
if(specialland == laCrossroads3) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
int y0 = y; if(y>32768) y0 -= 65536;
|
||||
@ -3060,7 +3046,7 @@ void setLandEuclid(cell *c) {
|
||||
c->wall = waBarrier;
|
||||
}
|
||||
}
|
||||
if(euclidland == laWarpCoast) {
|
||||
if(specialland == laWarpCoast) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
|
||||
@ -3516,7 +3502,7 @@ bool is02(int i) { return i == 0 || i == 2; }
|
||||
|
||||
// This function generates all lands. Warning: it's very long!
|
||||
void setdist(cell *c, int d, cell *from) {
|
||||
|
||||
|
||||
if(signed(c->mpdist) <= d) return;
|
||||
if(c->mpdist > d+1 && d != BARLEV) setdist(c, d+1, from);
|
||||
c->mpdist = d;
|
||||
@ -3546,7 +3532,7 @@ void setdist(cell *c, int d, cell *from) {
|
||||
|
||||
if(sphere || torus) setLandSphere(c);
|
||||
else if(euclid) setLandEuclid(c);
|
||||
if(quotient) { setland(c, euclidland); setLandQuotient(c); }
|
||||
if(quotient) { setland(c, specialland); setLandQuotient(c); }
|
||||
|
||||
// if(chaosmode) setland(c, getCLand(c));
|
||||
}
|
||||
@ -4135,7 +4121,7 @@ void setdist(cell *c, int d, cell *from) {
|
||||
}
|
||||
|
||||
if(c->land == laHell) {
|
||||
if(hrand(1000) < 36 && celldist(c) >= 3) {
|
||||
if(hrand(1000) < (purehepta ? 16 : 36) && celldist(c) >= 3) {
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cell *c2 = createMov(c, i);
|
||||
setdist(c2, d+1, c);
|
||||
@ -5586,8 +5572,8 @@ void wandering() {
|
||||
if(inmirror(c)) continue;
|
||||
|
||||
if(smallbounded && !c->item && hrand(5) == 0 && c->land != laHalloween) {
|
||||
if(passable(c, NULL, 0) || euclidland == laKraken) {
|
||||
if(!haveOrbPower() && euclidland != laHell) for(int it=0; it<1000 && !c->item; it++)
|
||||
if(passable(c, NULL, 0) || specialland == laKraken) {
|
||||
if(!haveOrbPower() && specialland != laHell) for(int it=0; it<1000 && !c->item; it++)
|
||||
placeLocalOrbs(c);
|
||||
if(!c->item) c->item = wanderingTreasure(c);
|
||||
if(c->item == itShard) {
|
||||
|
162
langen.cpp
162
langen.cpp
@ -16,13 +16,18 @@ using namespace std;
|
||||
|
||||
template<class T> int size(T x) { return x.size(); }
|
||||
|
||||
#define NUMLAN 6
|
||||
#define NUMLAN 7
|
||||
|
||||
// language generator
|
||||
|
||||
const char *escape(string s, string dft);
|
||||
|
||||
template<class T> struct dictionary {
|
||||
map<string, T> m;
|
||||
void add(const string& s, const T& val) { m[s] = val; }
|
||||
void add(const string& s, const T& val) {
|
||||
if(m.count(s)) add(s + " [repeat]", val);
|
||||
else m[s] = val;
|
||||
}
|
||||
T& operator [] (const string& s) { return m[s]; }
|
||||
int count(const string& s) { return m.count(s); }
|
||||
void clear() { m.clear(); }
|
||||
@ -88,7 +93,14 @@ typedef unsigned hashcode;
|
||||
|
||||
hashcode hashval;
|
||||
|
||||
bool isrepeat(const string& s) {
|
||||
return s.find(" [repeat]") != string::npos;
|
||||
}
|
||||
|
||||
hashcode langhash(const string& s) {
|
||||
if(isrepeat(s)) {
|
||||
return langhash(s.substr(0, s.size() - 9)) + 1;
|
||||
}
|
||||
hashcode r = 0;
|
||||
for(int i=0; i<size(s); i++) r = hashval * r + s[i];
|
||||
return r;
|
||||
@ -133,6 +145,64 @@ void setstats(set<string>& s, const char* bn) {
|
||||
printf("// %-10s %5d %5d\n", bn, tc, tlen);
|
||||
}
|
||||
|
||||
void langPL() {
|
||||
#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
|
||||
}
|
||||
|
||||
void langTR() {
|
||||
#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
|
||||
}
|
||||
|
||||
void langCZ() {
|
||||
#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
|
||||
}
|
||||
|
||||
void langRU() {
|
||||
#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
|
||||
}
|
||||
|
||||
void langDE() {
|
||||
#define S(a,b) d[5].add(a,b);
|
||||
#define N(a,b,c,d,e) \
|
||||
{noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = e; nouns[5].add(a,n);}
|
||||
#include "language-de.cpp"
|
||||
#undef N
|
||||
#undef S
|
||||
}
|
||||
|
||||
void langPT() {
|
||||
#define S(a,b) d[6].add(a,b);
|
||||
#define N(a,b,c,d,e) \
|
||||
{noun n; n.genus = b; n.nom = c; n.nomp = d; n.abl = e; nouns[6].add(a,n);}
|
||||
#include "language-ptbr.cpp"
|
||||
#undef N
|
||||
#undef S
|
||||
}
|
||||
|
||||
int completeness[NUMLAN];
|
||||
|
||||
int main() {
|
||||
|
||||
nothe.insert("R'Lyeh");
|
||||
@ -146,42 +216,8 @@ int main() {
|
||||
allchars.insert("ᵈ");
|
||||
allchars.insert("δ");
|
||||
|
||||
#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
|
||||
|
||||
#define S(a,b) d[5].add(a,b);
|
||||
#define N(a,b,c,d,e) \
|
||||
{noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = e; nouns[5].add(a,n);}
|
||||
#include "language-de.cpp"
|
||||
#undef N
|
||||
#undef S
|
||||
langPL(); langCZ(); langRU();
|
||||
langTR(); langDE(); langPT();
|
||||
|
||||
// verify
|
||||
set<string> s;
|
||||
@ -189,12 +225,24 @@ int main() {
|
||||
for(map<string,string>::iterator it = d[i].m.begin(); it != d[i].m.end(); it++)
|
||||
s.insert(it->first);
|
||||
|
||||
printf("// DO NOT EDIT -- this file is generated automatically with langen\n\n");
|
||||
|
||||
for(set<string>::iterator x=s.begin(); x != s.end(); x++) {
|
||||
string mis = "";
|
||||
for(int i=1; i<NUMLAN; i++) if(d[i].count(*x) == 0)
|
||||
mis += d[i]["EN"];
|
||||
if(mis != "")
|
||||
printf("// #warning Missing [%s]: %s\n", mis.c_str(), escape(*x, "?"));
|
||||
string mis = "", mis1 = "";
|
||||
for(int i=1; i<NUMLAN; i++) if(d[i].count(*x) == 0) {
|
||||
string which = d[i]["EN"];
|
||||
if(which != "TR" && which != "DE" && which != "PT-BR")
|
||||
mis += which;
|
||||
else
|
||||
mis1 += which;
|
||||
}
|
||||
if(mis != "" && !isrepeat(*x))
|
||||
printf("// #warning Missing [%s/%s]: %s\n", mis.c_str(), mis1.c_str(), escape(*x, "?"));
|
||||
|
||||
if(!isrepeat(*x)) {
|
||||
completeness[0]++;
|
||||
for(int i=1; i<NUMLAN; i++) if(d[i].count(*x)) completeness[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
s.clear();
|
||||
@ -204,11 +252,20 @@ int main() {
|
||||
s.insert(it->first);
|
||||
|
||||
for(set<string>::iterator x=s.begin(); x != s.end(); x++) {
|
||||
string mis = "";
|
||||
for(int i=1; i<NUMLAN; i++) if(nouns[i].count(*x) == 0)
|
||||
mis += d[i]["EN"];
|
||||
if(mis != "")
|
||||
printf("// #warning Missing [%s]: %s\n", mis.c_str(), escape(*x, "?"));
|
||||
string mis = "", mis1 = "";
|
||||
for(int i=1; i<NUMLAN; i++) if(nouns[i].count(*x) == 0) {
|
||||
string which = d[i]["EN"];
|
||||
if(which != "TR" && which != "DE" && which != "PT-BR")
|
||||
mis += which;
|
||||
else mis1 += which;
|
||||
}
|
||||
if(mis != "" && !isrepeat(*x))
|
||||
printf("// #warning Missing [%s/%s]: %s\n", mis.c_str(), mis1.c_str(), escape(*x, "?"));
|
||||
|
||||
if(!isrepeat(*x)) {
|
||||
completeness[0]++;
|
||||
for(int i=1; i<NUMLAN; i++) if(nouns[i].count(*x)) completeness[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CHECKALL
|
||||
@ -240,13 +297,16 @@ int main() {
|
||||
// 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<c; i++) printf("\"%s\",", vchars[i].c_str());
|
||||
printf("};\n");
|
||||
printf("//javastring = \"%s\";\n", javastring.c_str());
|
||||
|
||||
printf("\nint transcompleteness[NUMLAN] = {");
|
||||
for(int i=0; i<NUMLAN; i++) printf("%d, ", completeness[i]);
|
||||
printf("};\n");
|
||||
|
||||
for(int i=1; i<NUMLAN; i++)
|
||||
for(map<string,string>::iterator it = d[i].m.begin(); it != d[i].m.end(); it++)
|
||||
@ -305,9 +365,11 @@ int main() {
|
||||
|
||||
for(map<hashcode,string>::iterator it = ms.begin(); it != ms.end(); it++) {
|
||||
string s = it->second;
|
||||
if(isrepeat(s)) printf("#if REPEATED\n");
|
||||
printf(" {0x%x, { // %s\n", it->first, escape(s, s));
|
||||
for(int i=1; i<NUMLAN; i++) printf(" %s,\n", escape(d[i][s], s));
|
||||
printf(" }},\n");
|
||||
if(isrepeat(s)) printf("#endif\n");
|
||||
}
|
||||
printf(" };\n\n");
|
||||
|
||||
@ -315,6 +377,7 @@ int main() {
|
||||
|
||||
for(map<hashcode,string>::iterator it = mn.begin(); it != mn.end(); it++) {
|
||||
string s = it->second;
|
||||
if(isrepeat(s)) printf("#if REPEATED\n");
|
||||
printf(" {0x%x, %d, { // \"%s\"\n", it->first,
|
||||
(nothe.count(s) ? 1:0) + (plural.count(s) ? 2:0),
|
||||
escape(s, s));
|
||||
@ -328,6 +391,7 @@ int main() {
|
||||
}
|
||||
|
||||
printf(" }},\n");
|
||||
if(isrepeat(s)) printf("#endif\n");
|
||||
}
|
||||
|
||||
printf(" };\n");
|
||||
|
117
language-cz.cpp
117
language-cz.cpp
@ -5780,9 +5780,9 @@ S(
|
||||
"Pokud na Zrcadlového ducha fyzicky zaútoèíš, zpomalíš ho tím, ale neznièíš "
|
||||
"-- ze zrcadla vyjdou další odrazy. Pokud ho chceš znièit nadobro, použij Mimiky.")
|
||||
|
||||
S(" (25 in the Orb Strategy mode)", " (25 ve Sférostrategickém módu)")
|
||||
S(" (50 in the Orb Strategy mode)", " (50 ve Sférostrategickém módu)")
|
||||
S(" (not in the Orb Strategy mode)", " (ne ve Sférostrategickém módu)")
|
||||
// S(" (25 in the Orb Strategy mode)", " (25 ve Sférostrategickém módu)")
|
||||
// S(" (50 in the Orb Strategy mode)", " (50 ve Sférostrategickém módu)")
|
||||
// S(" (not in the Orb Strategy mode)", " (ne ve Sférostrategickém módu)")
|
||||
|
||||
/*
|
||||
"NEW_ACHIEVEMENT_8_19_NAME" "Totální vítìzství"
|
||||
@ -5872,8 +5872,115 @@ S(
|
||||
S("puzzles and exploration", "hádanky a zkoumání")
|
||||
|
||||
S("Zebra quotient", "kvocient Zebra")
|
||||
S("cheats", "cheaty")
|
||||
S("field quotient", "tělesový kvocient")
|
||||
S("help for keyboard user", "pomoc pro uživatele klávesnice")
|
||||
S("mark heptagons", "označit sedmiúhelníky")
|
||||
S("cheats", "cheaty")
|
||||
S("help for keyboard users", "pomoc pro uživatele klávesnice")
|
||||
|
||||
S("Zebra quotient", "kvocient Zebra")
|
||||
S("field quotient", "tělesový kvocient")
|
||||
S("mark heptagons", "označit sedmiúhelníky")
|
||||
S("projection", "projekce")
|
||||
S("compass size", "velikost kompasu")
|
||||
|
||||
S("Collect as many Dodecahedra as you can, then return here!",
|
||||
"Získej co možná nejvíc Dvanáctistěnů, a potom se vrať sem!")
|
||||
|
||||
S("reset all configuration", "vyresetovat konfiguraci")
|
||||
S("Are you sure?", "Určitě?")
|
||||
S("yes, and delete the config file", "ano, a vymaž i konfigurační soubor")
|
||||
S("yes", "ano")
|
||||
S("cancel", "zrušit")
|
||||
S("reset the special game modes", "vyresetovat speciální herní módy")
|
||||
|
||||
// extra flavor messages for the OSM
|
||||
|
||||
S("You feel the presence of free saves on the Crossroads.",
|
||||
"Cítíš, že na Křižovatce si můžeš zdarma uložit hru.")
|
||||
|
||||
S("You feel the Orbs of Yendor nearby...",
|
||||
"Cítíš blízkost Yendorských Sfér...")
|
||||
|
||||
S("You feel the Orbs of Yendor in the Crossroads...",
|
||||
"Cítíš Yendorské Sféry na Křižovatce...")
|
||||
|
||||
S("You feel the Orbs of Yendor everywhere...",
|
||||
"Cítíš Yendorské Sféry všude...")
|
||||
|
||||
S("You have gained an offensive power!",
|
||||
"Získal jsi útočnou schopnost!")
|
||||
|
||||
S("A small reward for braving the Hell.",
|
||||
"Malá odměna za to, že ses postavil Peklu.")
|
||||
|
||||
S(" (mirrored)", " (zrcadlená)")
|
||||
S(" (used %1 times)", " (použitá %1krát)")
|
||||
S("Extras:", "Extra:") // extra Orbs gained in OSM
|
||||
|
||||
// cheats
|
||||
|
||||
S("unlock Orbs of Yendor", "odemkni Yendorské Sféry")
|
||||
S("Collected the keys!", "Získal jsi klíče!");
|
||||
S("Saved the Princess!", "Zachránil jsi Princeznu!")
|
||||
S("save a Princess", "zachraň Princeznu")
|
||||
|
||||
// other
|
||||
|
||||
S("Note for mobiles", "Poznámka pro mobilní telefony")
|
||||
S(
|
||||
"This tutorial is designed for computers, "
|
||||
"and keys are given for all actions. It will "
|
||||
"work without a keyboard though, although less "
|
||||
"comfortably -- just ignore the keys "
|
||||
"given and select options from MENU.\n\n"
|
||||
"Select 'next slide' from MENU.",
|
||||
|
||||
"Tento tutorial je navržený pro počítače a u všech akcí "
|
||||
"jsou uvedeny klávesy. Funguje i bez klávesnice, i když "
|
||||
"ne tak pohodlně -- prostě ignorujte udávané klávesy a "
|
||||
"vybírejte možnosti z MENU.\n\n"
|
||||
"Vyber z MENU 'další snímek'.")
|
||||
|
||||
S("skip the start menu", "přeskoč menu 'start'")
|
||||
S("quick mouse", "rychlá myš")
|
||||
S("This combination is known to be buggy at the moment.", "Tato kombinace možností v současné době nepracuje správně.")
|
||||
|
||||
// extra Princess texts
|
||||
|
||||
S("\"I do not like butterflies. They are treacherous.\"",
|
||||
"\"Nesnáším motýly. Jsou zrádní.\"")
|
||||
|
||||
S("\"I hate roses.\"", "\"Nenávidím růže.\"")
|
||||
|
||||
S("\"In this world there is plenty of space for everyone. We do not need wars.\"",
|
||||
"\"V tomhle světě je dost místa pro všechny. Nepotřebujeme války.\"")
|
||||
|
||||
S("\"Only the stupid hyperbugs do not understand this.\"",
|
||||
"\"Jenom ti hloupí hyperhmyzáci tomu nerozumějí.\"")
|
||||
|
||||
S("\"I have once talked to a Yendorian researcher... he was only interested in infinite trees.\"",
|
||||
"\"Jednou se mnou mluvil jeden Yendorský výzkumník... zajímal se jenom o nekonečné stromy.\"")
|
||||
|
||||
S("\"Infinite trees are boring. I prefer other graphs.\"",
|
||||
"\"Nekonečné stromy jsou nudné. Mám raději jiné grafy.\"")
|
||||
|
||||
// new start menu
|
||||
S("skip the start menu", "přeskoč menu 'start'")
|
||||
|
||||
S("HyperRogue classic", "klasický HyperRogue")
|
||||
S("explore the world, collect treasures", "zkoumej svět, sbírej poklady")
|
||||
S("do not get checkmated", "vyhni se šachmatu")
|
||||
S("use your Orbs in tough situations", "v obtížných situacích používej Sféry")
|
||||
S("continuous spacetime", "spojitý časoprostor")
|
||||
S("(most achievements are not available)", "(většina achievementů není k dispozici)")
|
||||
S("learn about hyperbolic geometry!", "nauč se o hyperbolické geometrii!")
|
||||
S("more options", "více možností")
|
||||
|
||||
S(
|
||||
"A strange land filled with mirrors. Break magic mirrors and mirage clouds to "
|
||||
"gain treasures and helpful Mimics.",
|
||||
"Podivný kraj plný zrcadel. Rozbíjej magická zrcadla a oblaky přeludů, abys získal poklady a užitečné Mimiky."
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
16582
language-data.cpp
Normal file
16582
language-data.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -4265,7 +4265,7 @@ S("Watch the Minkowski hyperboloid or the hypersian rug mode with the "
|
||||
"Oglądaj hiperboloidę Minkowskiego albo tryb hiperskiego dywanu przez czerwono-turkusowe okulary 3D.")
|
||||
|
||||
S("0 - return", "0 - powrót")
|
||||
S("return", "powót")
|
||||
S("return", "powrót")
|
||||
S("F1 - help", "F1 - pomoc")
|
||||
|
||||
// for the conformal polynomial
|
||||
@ -5780,10 +5780,6 @@ S(
|
||||
|
||||
S("puzzles and exploration", "zagadki i zwiedzanie")
|
||||
|
||||
S("cheats", "oszustwa")
|
||||
S("help for keyboard user", "pomoc dla użytkowników klawiatury")
|
||||
S("mark heptagons", "oznacz siedmiokąty")
|
||||
|
||||
S("Collect as many Dodecahedra as you can, then return here!",
|
||||
"Zbierz jak najwięcej Dwunastościanów i tu wróć!")
|
||||
|
||||
@ -5793,6 +5789,97 @@ S("yes, and delete the config file", "tak, i skasuj plik konfiguracyjny")
|
||||
S("yes", "tak")
|
||||
S("cancel", "anuluj")
|
||||
S("reset the special game modes", "zresetuj specjalne tryby gry")
|
||||
|
||||
// extra flavor messages for the OSM
|
||||
|
||||
S("You feel the presence of free saves on the Crossroads.",
|
||||
"Wyczuwasz bezpieczeństwo na Skrzyżowaniach.")
|
||||
|
||||
S("You feel the Orbs of Yendor nearby...",
|
||||
"Czujesz w pobliżu Sfery Yendoru...")
|
||||
|
||||
S("You feel the Orbs of Yendor in the Crossroads...",
|
||||
"Wyczuwasz Sfery Yendoru na Skrzyżowaniach...")
|
||||
|
||||
S("You feel the Orbs of Yendor everywhere...",
|
||||
"Wyczuwasz Sfery Yendoru, wszędzie...")
|
||||
|
||||
S("You have gained an offensive power!",
|
||||
"Zdobywasz moc ofensywną!")
|
||||
|
||||
S("A small reward for braving the Hell.",
|
||||
"Drobna nagroda za zmierzenie się z Piekłem.")
|
||||
|
||||
S(" (mirrored)", " (odbite)")
|
||||
S(" (used %1 times)", " (użyte %1 razy)")
|
||||
S("Extras:", "Dodatkowe:") // extra Orbs gained in OSM
|
||||
|
||||
// cheats
|
||||
|
||||
S("unlock Orbs of Yendor", "otwórz Sfery Yendoru")
|
||||
S("Collected the keys!", "Zebrano klucze!");
|
||||
S("Saved the Princess!", "Uratowano Księżniczkę!")
|
||||
S("save a Princess", "uratuj Księżniczkę")
|
||||
|
||||
// other
|
||||
|
||||
S("Note for mobiles", "Notka dla urządzeń mobilnych")
|
||||
S(
|
||||
"This tutorial is designed for computers, "
|
||||
"and keys are given for all actions. It will "
|
||||
"work without a keyboard though, although less "
|
||||
"comfortably -- just ignore the keys "
|
||||
"given and select options from MENU.\n\n"
|
||||
"Select 'next slide' from MENU.",
|
||||
|
||||
"Ten tutorial jest przeznaczony głównie "
|
||||
"dla komputerów, i klawisze są podane "
|
||||
"dla wszystkich akcji. Działa jednak bez "
|
||||
"klawiatury, choć mniej wygodnie -- "
|
||||
"ignoruj klawisze i wybieraj opcje z MENU.\n\n"
|
||||
"given and select options from MENU.\n\n"
|
||||
"Wybierz z MENU 'następny slajd'.")
|
||||
|
||||
S("quick mouse", "szybka mysz")
|
||||
S("This combination is known to be buggy at the moment.", "Ta kombinacja opcji obecnie działa błędnie.")
|
||||
|
||||
// extra Princess texts
|
||||
|
||||
S("\"I do not like butterflies. They are treacherous.\"",
|
||||
"\"Nie lubię motyli. Są zdradzieckie.\"")
|
||||
|
||||
S("\"I hate roses.\"", "\"Nienawidzę róż.\"")
|
||||
|
||||
S("\"In this world there is plenty of space for everyone. We do not need wars.\"",
|
||||
"\"W tym świecie jest dość miejsca dla każdego. Nie potrzebujemy wojen.\"")
|
||||
|
||||
S("\"Only the stupid hyperbugs do not understand this.\"",
|
||||
"\"Tylko głupie hiperinsekty tego nie rozumieją.\"")
|
||||
|
||||
S("\"I have once talked to a Yendorian researcher... he was only interested in infinite trees.\"",
|
||||
"\"Odwiedził mnie raz badacz Yendoriański... interesowały go tylko nieskończone drzewa.\"")
|
||||
|
||||
S("\"Infinite trees are boring. I prefer other graphs.\"",
|
||||
"\"Nieskończone drzewa są nudne. Wolę inne grafy.\"")
|
||||
|
||||
// new start menu
|
||||
S("skip the start menu", "pomiń menu startowe")
|
||||
|
||||
S("HyperRogue classic", "tryb klasyczny HyperRogue")
|
||||
S("explore the world, collect treasures", "zwiedzaj świat i zbieraj skarby")
|
||||
S("do not get checkmated", "nie daj się zaszachować")
|
||||
S("use your Orbs in tough situations", "używaj Sfer w trudnych sytuacjach")
|
||||
S("continuous spacetime", "ciągła czasoprzestrzeń")
|
||||
S("(most achievements are not available)", "(większość osiągnięć niedostępna)")
|
||||
S("learn about hyperbolic geometry!", "dowiedz się więcej o geometrii hiperbolicznej!")
|
||||
S("more options", "więcej opcji")
|
||||
|
||||
S(
|
||||
"A strange land filled with mirrors. Break magic mirrors and mirage clouds to "
|
||||
"gain treasures and helpful Mimics.",
|
||||
"Dziwna kraina pełna luster. Zbijaj magiczne lustra i mirażowe chmury, "
|
||||
"by zdobywać skarby i przyjazne Mimiki."
|
||||
)
|
||||
|
||||
#undef Orb
|
||||
|
||||
|
5979
language-ptbr.cpp
Normal file
5979
language-ptbr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
474
language-ru.cpp
474
language-ru.cpp
@ -2189,6 +2189,9 @@ S("configure player 1", "настройки игрока 1")
|
||||
S("configure player 2", "настройки игрока 2")
|
||||
S("configure player 3", "настройки игрока 3")
|
||||
S("configure player 4", "настройки игрока 4")
|
||||
S("configure player 5", "настройки игрока 5")
|
||||
S("configure player 6", "настройки игрока 6")
|
||||
S("configure player 7", "настройки игрока 7")
|
||||
S("configure panning", "настройки прокрутки")
|
||||
S("configure joystick axes", "настройка джойстика")
|
||||
S("continue playing", "продолжить игру")
|
||||
@ -5590,5 +5593,476 @@ S(
|
||||
"Нажмите '5', чтобы выйти из режима Руководства."
|
||||
)
|
||||
|
||||
// Orb Strategy mode
|
||||
S("Orb Strategy mode", "режим стратегии сфер")
|
||||
|
||||
S(
|
||||
"You are playing in the Orb Strategy Mode. Collecting treasure "
|
||||
"gives you access to magical Orb powers. In this mode, "
|
||||
"unlocking requirements are generally higher, and "
|
||||
"several quests and lands "
|
||||
"give you extremely powerful Orbs of the Mirror.\n",
|
||||
|
||||
"Ты играешь в режим стратегии сфер. Собирай сокровища и получай "
|
||||
"доступ к силе магических сфер. В этом режиме условия "
|
||||
"открытия доступа, как правило, выше, а некоторые земли и миссии "
|
||||
"дадут тебе очень сильные Сферы зеркала.\n")
|
||||
|
||||
S("The treasure gives your magical powers!", "Сокровище дало тебе магическую силу!")
|
||||
S("Press 'i' to access your magical powers.", "Нажми 'i' для доступа к своим магическим силам.")
|
||||
S("inventory", "твои сферы")
|
||||
S("mirror what?", "что отразить?")
|
||||
S("Which orb to use?", "Какую сферу использовать?")
|
||||
S("Unlocked by: %1 in %2", "Разблокирована: %1 %abl2")
|
||||
S(" (next at %1)", " (следующий при %1)")
|
||||
S(" (next at %1 to %2)", " (следующий при %1 в %2)")
|
||||
S("Number of uses left: %1", "Осталось применений: %1")
|
||||
S("You mirror %the1.", "Ты отразил %a1.")
|
||||
S("You need to stand next to a magic mirror or cloud to use %the1.",
|
||||
"Ты должен стоять рядом с магическим зеркалом или облаком, чтобы использовать %a1.")
|
||||
S("Each orb type can be mirrored only once.", "Каждый тип сфер может быть отражён только один раз.")
|
||||
|
||||
S(
|
||||
"\n\nIn the Orb Strategy Mode, Orbs of Yendor appear in Hell after "
|
||||
"you collect 25 Demon Daisies in Hell, in Crossroads/Ocean after you collect 50, "
|
||||
"and everywhere after you collect 100.",
|
||||
|
||||
"\n\nВ режим стратегии сфер Сфера Йендора появляется в Аду, "
|
||||
"когда ты соберёшь 25 Адских Ромашек, на Перекрёстке и а Океана, когда ты соберёшь 50, "
|
||||
"и везде, когда ты соберёшь 100."
|
||||
);
|
||||
|
||||
S(
|
||||
"\n\nIn the Orb Strategy Mode, dead orbs are available once you collect "
|
||||
"10 Necromancer Totems in the Graveyard.",
|
||||
|
||||
"\n\nВ режиме стратегии сфер Мёртвые сферы доступны после сбора "
|
||||
"десяти Тотемов некроманта на Кладбище.")
|
||||
|
||||
S(
|
||||
"\n\nIn the Orb Strategy Mode, Orbs of Safety can be gained by "
|
||||
"collecting Phoenix Feathers in the Land of Eternal Motion. "
|
||||
"You can also find unlimited Orbs of Safety in the Crossroads "
|
||||
"and the Ocean (after collecting 25 Phoenix Feathers) "
|
||||
"and in the Prairie.",
|
||||
|
||||
"\n\nВ режиме стратегии сфер Сферу безопасности можно получить, "
|
||||
"Перья феникса в Земле вечного движения. "
|
||||
"Также можно найти неограниченные Сферы вечного движения на Перекрёстке "
|
||||
"и в Океане (когда соберёшь 25 Перьев феникса) и в Прерии."
|
||||
)
|
||||
|
||||
S(
|
||||
"\n\nCollect %the1 to gain an extra Orb of the Mirror. "
|
||||
"You can gain further Orbs of the Mirror by collecting 2, 4, 8...",
|
||||
|
||||
"\n\nСобери %a1, чтобы получить дополнительную Сферу зеркала. "
|
||||
"Ты получишь следующую сферу, когда соберёшь 2, 4, 8..."
|
||||
)
|
||||
|
||||
S(
|
||||
"\n\nIn the Orb Strategy Mode, the Orb of Luck also "
|
||||
"significantly increases the frequency of Great Walls, Crossroads IV, "
|
||||
"and sub-lands.",
|
||||
|
||||
"\n\nВ режиме стратегии сфер Сфера удачи также заметно "
|
||||
"увеличивает частоту Великих стен, Перекрёстков IV "
|
||||
"и под-земель.")
|
||||
|
||||
S("\n\nIn the Orb Strategy Mode, each 25 Necromancer's Totems "
|
||||
"you are given a random offensive Orb.",
|
||||
|
||||
"\n\n режиме стратегии сфер каждый 25 Тотемов некроманта "
|
||||
"дают тебе случайную атакующую сферу.")
|
||||
|
||||
S(
|
||||
"Use Orb of the Mirror to gain copies of one of your Orbs; "
|
||||
"mirroring weaker Orbs usually yields more copies. "
|
||||
"It can only be used once per Orb type, "
|
||||
"and only when you are next to a mirror.",
|
||||
|
||||
"Используй Сферу зеркала, чтобы получить копии одной из твоих сфер; "
|
||||
"отражение слабых сфер обычно даёт больше копий. "
|
||||
"Ты можешь отражать каждый тип сферы лишь один раз, "
|
||||
"и только когда ты рядом с зеркалом.")
|
||||
|
||||
S("Uses to gain: %1", "Получишь применений: %1")
|
||||
S("already mirrored", "уже была отражена")
|
||||
|
||||
N("your orbs", GEN_F, "Твои Сферы", "Твои Сферы", "Твои Сферы", "Твоим Сферами")
|
||||
S("Click this to see your orbs.", "Нажми, чтобы увидеть твои Сферы.")
|
||||
|
||||
// peaceful mode
|
||||
S("configure keys/joysticks", "настройки клавиш/джойстика")
|
||||
S("peaceful mode", "мирный режим")
|
||||
|
||||
// config changes
|
||||
S("Press F5 or 'o' to try again!", "Нажми F5 или 'o', чтобы попробовать ещё раз!")
|
||||
S("aura brightness", "яркость ауры")
|
||||
S("aura smoothening factor", "сглаживание ауры")
|
||||
S("graphics configuration", "настройка графики")
|
||||
S("special display modes", "специальные режимы отображения")
|
||||
S("openGL mode", "режим OpenGL")
|
||||
S("anti-aliasing", "anti-aliasing")
|
||||
S("line width", "широта линии")
|
||||
S("configure panning and general keys", "настроить панораму и общие клавиши")
|
||||
|
||||
S("\n\nHint: use 'm' to toggle cells quickly",
|
||||
"\n\nПодсказка: используй 'm', чтобы быстро переключать клетки");
|
||||
|
||||
// cell pattern names
|
||||
S("football", "футбол")
|
||||
S("dark rainbow landscape", "тёмная радуга")
|
||||
S("field pattern", "узор поля")
|
||||
S("field pattern C", "узор поля C")
|
||||
S("field pattern D", "узор поля D")
|
||||
S("field pattern N", "узор поля N")
|
||||
S("field pattern S", "узор поля S")
|
||||
S("four triangles", "четыре треугольника")
|
||||
S("big triangles: rings", "большие треугольники: кольца")
|
||||
|
||||
// missing for the Tutorial
|
||||
S("tutorial", "руководство")
|
||||
S("This Orb is not compatible with the Tutorial.", "Эта сфера не совместима с Руководством.")
|
||||
|
||||
// local scores
|
||||
S("turns", "ходы")
|
||||
S("cells", "клетки")
|
||||
S("sort", "сортируй")
|
||||
S("choose", "выбор")
|
||||
S("play", "играй")
|
||||
|
||||
// draw editor
|
||||
S("autochoose", "автовыбор")
|
||||
S("c = choose", "c = выбор")
|
||||
S("b = switch auto", "b = автопереключение")
|
||||
|
||||
// mission screen hints
|
||||
|
||||
S(
|
||||
"If you collect too many treasures in a given land, it will become "
|
||||
"extremely dangerous. Try other lands once you have enough!",
|
||||
"Если ты соберёшь слишком много сокровищ в одной земле, она станет "
|
||||
"весьма опасной. Попробуй другую землю, когда наберёшь достаточно сокровищ здесь!");
|
||||
|
||||
S(
|
||||
"Remember that you can right click almost anything for more information.",
|
||||
"Помни, что правая кнопка мыши даст информацию практически обо всём.")
|
||||
|
||||
S("Want to understand the geometry in HyperRogue? Try the Tutorial!",
|
||||
"Хочешь понять геометрию в HyperRogue? Воспользуйся Руководством!");
|
||||
|
||||
S(
|
||||
"Collecting 25 treasures in a given land may be dangerous, "
|
||||
"but allows magical Orbs of this land to appear in other places!",
|
||||
"Собирать 25 в одной земле довольно опасно, но это позволяет Сферам "
|
||||
"из этой земли появляться в других местах!")
|
||||
|
||||
S(
|
||||
"Press ESC to view this screen during the game.",
|
||||
"Нажми ESC, чтобы увидеть этот экран во время игры.")
|
||||
|
||||
S("The 'world overview' shows all the lands in HyperRogue.",
|
||||
"'Обзор мира' покажет все земли в HyperRogue."
|
||||
)
|
||||
|
||||
S("Press 'o' to see all the lands in HyperRogue.",
|
||||
"Нажми 'o', чтобы увидеть все земли в HyperRogue.")
|
||||
|
||||
S(
|
||||
"Want another type of game? Want more challenge?\n"
|
||||
"HyperRogue has many special modes and challenges that "
|
||||
"significantly change the gameplay. Try them!",
|
||||
|
||||
"Хочешь другой тип игры? Хочешь посложнее?\n"
|
||||
"HyperRogue содержит много специальных режимов, "
|
||||
"заметно меняющих игру. Попробуй их!")
|
||||
|
||||
S(
|
||||
"Hyperbolic geometry can be shown in many ways.",
|
||||
"На гиперболическую геометрию можно смотреть с разных сторон.")
|
||||
|
||||
S(
|
||||
"You do not want to lose the game from a single mistake?\n"
|
||||
"Do you want to use the Orbs strategically?\n"
|
||||
"Try the Orb Strategy mode!",
|
||||
|
||||
"Не хочешь проигрывать из-за одной ошибки?\n"
|
||||
"Хочешь научить аккуратно использовать Сферы?\n"
|
||||
"Попробуй режим стратегии сфер!")
|
||||
|
||||
S(
|
||||
"Do you think you are playing on a ball? "
|
||||
"This is far from the truth!\n",
|
||||
|
||||
"Думаешь, ты играешь на сфере? Как же это далеко от правды!\n")
|
||||
|
||||
S(
|
||||
"Did you know that the path you take during the game "
|
||||
"is usually very close to a straight line?\n",
|
||||
|
||||
"Ты знал, что путь, который ты проходишь за игру, "
|
||||
"обычно очень близок к прямой линии?")
|
||||
|
||||
S("Show me!", "Покажи!")
|
||||
|
||||
S(
|
||||
"You are %1 cells away from the starting point, or "
|
||||
"the place where you used an Orb of Safety last time. "
|
||||
"There are %2 such cells.\n",
|
||||
|
||||
"Ты на расстоянии %1 клеток от начала пути или "
|
||||
"от того места, где ты в последний раз использовал Сферу безопасности. "
|
||||
"Всего таких клеток %2.\n")
|
||||
|
||||
S("about ", "примерно ")
|
||||
S(" (%1 more digits)", " (ещё цифр: %1)")
|
||||
|
||||
S("see how it ended", "смотри, как всё закончилось")
|
||||
|
||||
// other missing/new things
|
||||
S("\n\nOrb unlocked: %1", "\n\nОткрыта сфера: %1")
|
||||
S("Orb unlocked: %1", "Открыта сфера: %1")
|
||||
S("\n\nSecondary orb: %1", "\n\nДополнительная сфера: %1")
|
||||
S(" to submerge", " на погружение")
|
||||
S(" to surface", " на поверхность")
|
||||
S("%The1 says, \"not this place, it looks even worse...\"",
|
||||
"%1 сказал, \"не это место, оно выглядит ещё хуже...\"")
|
||||
S("torus", "тор")
|
||||
S(" (click to use)", " (нажми, чтобы использовать)")
|
||||
N("Hall of Mirrors", GEN_O, "Зеркальный зал", "Зеркальные залы", "Зеркальный зал", "в Зеркальном зале")
|
||||
Orb("the Mirror", "Зеркала")
|
||||
N("Reflection", GEN_N, "Отражение", "Отражения", "Отражение", "в Отражении")
|
||||
N("mirror wall", GEN_F, "зеркальная стена", "зеркальные стены", "зеркальную стену", "зеркальной стеной")
|
||||
|
||||
S("This would only move you deeper into the trap!",
|
||||
"Это только уведёт тебя глубже в ловушку!");
|
||||
|
||||
S("You swing your sword at the mirror.", "Ты размахиваешь мечом в сторону зеркала.");
|
||||
N("Mimic", GEN_M, "Мимик", "Мимики", "Мимика", "Мимиком")
|
||||
N("Narcissist", GEN_M, "Нарциссист", "Нарциссисты", "Нарциссиста", "Нарциссистом")
|
||||
N("Mirror Spirit", GEN_M, "Зеркальный дух", "Зеркальные духи", "Зеркального духа", "Зеркальным духом")
|
||||
|
||||
S("This person loves to look at their own reflection in the mirror. "
|
||||
"He believes himself to be one of the most important creatures in this world, "
|
||||
"and hates those who do not admire him.",
|
||||
|
||||
"Этот человек любит глядеть на своё отражение в зеркале. "
|
||||
"Он верит, что он -- один из самых важных в существ этого мира, "
|
||||
"и ненавидит любого, кто не восхищается им.")
|
||||
|
||||
S(
|
||||
"A long time ago a mighty warrior was guarding the mirrors from being broken. "
|
||||
"While this warrior is no longer alive, his reflections have gained life of "
|
||||
"their own, and will punish the intruders.\n\n"
|
||||
"If you attack a Mirror Spirit physically, it is delayed, but not destroyed -- "
|
||||
"more reflections will come out of the mirror. Use Mimics to destroy them.",
|
||||
|
||||
"Давным-давно могучий воин охранял эти зеркала, чтобы никто их не разбил. "
|
||||
"Хотя воин давно мёртв, его отражения живы, "
|
||||
"и они накажут незваных гостей.\n\n"
|
||||
"Если ты атакуешь Зеркального духа физически, он замедляется, но не погибает -- "
|
||||
"больше отражений выходит из зеркала. Используй Мимиков, чтобы уничтожать их.")
|
||||
|
||||
// S(" (25 in the Orb Strategy mode)", " (25 в режиме стратегии сфер)")
|
||||
// S(" (50 in the Orb Strategy mode)", " (50 в режиме стратегии сфер)")
|
||||
// S(" (not in the Orb Strategy mode)", " (не в режиме стратегии сфер)")
|
||||
|
||||
/*
|
||||
"NEW_ACHIEVEMENT_8_19_NAME" "Общая победа"
|
||||
"NEW_ACHIEVEMENT_8_19_DESC" "В режиме стратегии сфер получить Сферу Йендора, Святой Грааль, Принцессу и 50 Гиперкамней."
|
||||
|
||||
added to old achievements:
|
||||
"(или 25 в режиме стратегии сфер)"
|
||||
"(или 50 в режиме стратегии сфер)"
|
||||
"(не в режиме стратегии сфер)"
|
||||
|
||||
These apparently have not been yet translated:
|
||||
|
||||
"NEW_ACHIEVEMENT_8_4_NAME" "Адепт Йендора"
|
||||
"NEW_ACHIEVEMENT_8_4_DESC" "Закончи миссию Йендора."
|
||||
"NEW_ACHIEVEMENT_8_5_NAME" "Мастер ключей"
|
||||
"NEW_ACHIEVEMENT_8_5_DESC" "Закончи 5 миссий Йендора."
|
||||
"NEW_ACHIEVEMENT_8_6_NAME" "Гроссмейстер ключей"
|
||||
"NEW_ACHIEVEMENT_8_6_DESC" "Закончи 15 миссий Йендора."
|
||||
"NEW_ACHIEVEMENT_8_7_NAME" "Адепт Тактики"
|
||||
"NEW_ACHIEVEMENT_8_7_DESC" "Получи 1000 очков в режиме тактики."
|
||||
"NEW_ACHIEVEMENT_8_8_NAME" "Мастер Тактики"
|
||||
"NEW_ACHIEVEMENT_8_8_DESC" "Получи 5000 очков в режиме тактики."
|
||||
"NEW_ACHIEVEMENT_8_9_NAME" "Гроссмейстер Тактики"
|
||||
"NEW_ACHIEVEMENT_8_9_DESC" "Получи 15000 очков в режиме тактики."
|
||||
"NEW_ACHIEVEMENT_8_10_NAME" "На другой стороне"
|
||||
"NEW_ACHIEVEMENT_8_10_DESC" "Найди и собери Зелёную траву."
|
||||
|
||||
*/
|
||||
|
||||
// peaceful texts
|
||||
|
||||
S("memory game", "игра 'память'")
|
||||
S("display hints", "показать подсказки")
|
||||
S("hyperbolic puzzles", "гиперболические паззлы")
|
||||
|
||||
// missing descriptions
|
||||
|
||||
S( "A strange land filled with mirrors. "
|
||||
"Break magic mirrors and enter clouds of mirage to "
|
||||
"gain treasures and helpful Mimics.",
|
||||
|
||||
"Странная земля, наполненная зеркалами. "
|
||||
"Разбивай магические зеркала и входи в облака миражей, "
|
||||
"чтобы найти сокровища и дружелюбных Мимиков.")
|
||||
|
||||
S(
|
||||
"A perfect mirror wall. It is unbreakable "
|
||||
"and impassable "
|
||||
"even for aethereal beings, and everything "
|
||||
"you see inside is just an image of "
|
||||
"the real world; you can swing your sword "
|
||||
"at them, but that will not destroy them "
|
||||
"in the real world. "
|
||||
"Mirror walls reflect Mimics, lightning bolts, and "
|
||||
"missiles perfectly.",
|
||||
|
||||
"Идеальная зеркальная стена. Невозможно сломать её или "
|
||||
"пройти через неё, даже для эфирных существ, "
|
||||
"и всё, что ты в ней видишь -- отражения реального мира. "
|
||||
"Ты можешь ударить по отражению мечом, "
|
||||
"но это не убьёт его в реальном мире. "
|
||||
"Стена идеально отражает Мимиков, молнии и ракеты. ")
|
||||
|
||||
S(
|
||||
"In the peaceful mode, you just explore the world, "
|
||||
"without any battles; there are also several "
|
||||
"navigational puzzles available. In the memory game, "
|
||||
"you have to collect as many Dodecahedra as you can, "
|
||||
"and return to the starting point -- hyperbolic geometry "
|
||||
"makes this extremely difficult! Other hyperbolic puzzles "
|
||||
"include the Burial Grounds (excavate the treasures "
|
||||
"using your magical sword), Galápagos (try to find an adult "
|
||||
"tortoise matching the baby), Camelot (find the center of "
|
||||
"a large hyperbolic circle), and Palace (follow the mouse). "
|
||||
"Other places listed are for exploration.",
|
||||
|
||||
"В мирном режиме ты можешь исследовать мир без битв; "
|
||||
"здесь также доступно несколько навигационных головоломок. "
|
||||
"В игре 'память' ты должен собрать как можно больше додекаэдров и "
|
||||
"вернуться в точку старта -- гиперболическая геометрия делает это "
|
||||
"крайне сложным! Другие паззлы включают Курганы (выкопай сокровища "
|
||||
"с помощью магического меча), Галапагосы (найди взрослую черепаху, "
|
||||
"соответствующую маленькой черепашке), Камелот (найди центр большого "
|
||||
"гиперболического круга) и Дворец (следуй за мышкой). "
|
||||
"Остальные места перечислены для изучения."
|
||||
);
|
||||
|
||||
S("puzzles and exploration", "головоломки и изучение")
|
||||
|
||||
S("Zebra quotient", "фактор Зебры")
|
||||
S("field quotient", "фактор поля")
|
||||
S("mark heptagons", "пометить семиугольники")
|
||||
S("projection", "проекция")
|
||||
S("compass size", "размер компаса")
|
||||
|
||||
S("Collect as many Dodecahedra as you can, then return here!",
|
||||
"Собери как можно больше Додекаэдров и вернись сюда!")
|
||||
|
||||
S("reset all configuration", "сбросить все настройки")
|
||||
S("Are you sure?", "Вы уверены?")
|
||||
S("yes, and delete the config file", "да, и удалить файл с настройками")
|
||||
S("yes", "да")
|
||||
S("cancel", "отменить")
|
||||
S("reset the special game modes", "сбросить специальные режимы")
|
||||
|
||||
// extra flavor messages for the OSM
|
||||
|
||||
S("You feel the presence of free saves on the Crossroads.",
|
||||
"Ты чувствуешь, что можешь безопасно сохраниться на перекрёстке.")
|
||||
|
||||
S("You feel the Orbs of Yendor nearby...",
|
||||
"Ты чувствуешь Сферы Йендора поблизости...")
|
||||
|
||||
S("You feel the Orbs of Yendor in the Crossroads...",
|
||||
"Ты чувствуешь Сферы Йендора на перекрёстке...")
|
||||
|
||||
S("You feel the Orbs of Yendor everywhere...",
|
||||
"Ты чувствуешь Сферы Йендора везде...")
|
||||
|
||||
S("You have gained an offensive power!",
|
||||
"Ты получил атакующую силу!")
|
||||
|
||||
S("A small reward for braving the Hell.",
|
||||
"Небольшая награда для прошедших сквозь Ад.")
|
||||
|
||||
S(" (mirrored)", " (отражено)")
|
||||
S(" (used %1 times)", " (использовано %1 раз)")
|
||||
S("Extras:", "Дополнительно:") // extra Orbs gained in OSM
|
||||
|
||||
// cheats
|
||||
|
||||
S("unlock Orbs of Yendor", "открыть Сферы Йендора")
|
||||
S("Collected the keys!", "Ключи собраны!");
|
||||
S("Saved the Princess!", "Принцесса спасена!")
|
||||
S("save a Princess", "спасти Принцессу")
|
||||
|
||||
// other
|
||||
|
||||
S("Note for mobiles", "Замечание для мобильных устройств")
|
||||
S(
|
||||
"This tutorial is designed for computers, "
|
||||
"and keys are given for all actions. It will "
|
||||
"work without a keyboard though, although less "
|
||||
"comfortably -- just ignore the keys "
|
||||
"given and select options from MENU.\n\n"
|
||||
"Select 'next slide' from MENU.",
|
||||
|
||||
"Это руководство сделано для компьютеров, "
|
||||
"и клавиши требуются для всех "
|
||||
"действий. Им можно пользоваться и "
|
||||
"без клавиатуры, хотя и не так удобно -- "
|
||||
"просто игнорируй их и выбирай действия в МЕНЮ.\n\n"
|
||||
"Выбери в МЕНЮ 'следующий слайд'.")
|
||||
|
||||
S("skip the start menu", "пропустить начальное меню")
|
||||
S("quick mouse", "быстрая мышь")
|
||||
S("This combination is known to be buggy at the moment.", "Эта комбинация пока что работает с ошибками.")
|
||||
|
||||
// extra Princess texts
|
||||
|
||||
S("\"I do not like butterflies. They are treacherous.\"",
|
||||
"\"Не люблю бабочек. Они предательницы.\"")
|
||||
|
||||
S("\"I hate roses.\"", "\"Ненавижу розы.\"")
|
||||
|
||||
S("\"In this world there is plenty of space for everyone. We do not need wars.\"",
|
||||
"\"В этом мире так много места для каждого. Вам не нужны войны.\"")
|
||||
|
||||
S("\"Only the stupid hyperbugs do not understand this.\"",
|
||||
"\"Только глупые гипержуки не понимают этого.\"")
|
||||
|
||||
S("\"I have once talked to a Yendorian researcher... he was only interested in infinite trees.\"",
|
||||
"\"Со мной беседовал Йендорский исследователь... его интересовали лишь бесконечные деревья.\"")
|
||||
|
||||
S("\"Infinite trees are boring. I prefer other graphs.\"",
|
||||
"\"Бесконечные деревья скучные. Предпочитаю другие графы.\"")
|
||||
|
||||
// new start menu
|
||||
S("skip the start menu", "пропустить начальное меню")
|
||||
|
||||
S("HyperRogue classic", "классический режим HyperRogue")
|
||||
S("explore the world, collect treasures", "изучай мир, собирай сокровища")
|
||||
S("do not get checkmated", "не дай поставить себе мат")
|
||||
S("use your Orbs in tough situations", "используй Сферы в трудных ситуациях")
|
||||
S("continuous spacetime", "непрерывное пространство и время")
|
||||
S("(most achievements are not available)", "(большинство достижений недоступно)")
|
||||
S("learn about hyperbolic geometry!", "узнай о гиперболической геометрии!")
|
||||
S("more options", "больше вариантов")
|
||||
|
||||
S(
|
||||
"A strange land filled with mirrors. Break magic mirrors and mirage clouds to "
|
||||
"gain treasures and helpful Mimics.",
|
||||
"Странная земля, полная зеркал. Разбивай волшебные зеркала и облака миражей, "
|
||||
"чтобы найти сокровища и дружелюбных Мимиков."
|
||||
)
|
||||
|
||||
#undef Orb
|
||||
|
||||
|
23
language.cpp
23
language.cpp
@ -3,7 +3,7 @@
|
||||
|
||||
// #define CHECKTRANS
|
||||
|
||||
#define NUMLAN 6
|
||||
#define NUMLAN 7
|
||||
|
||||
struct stringpar {
|
||||
string v;
|
||||
@ -243,6 +243,27 @@ void parrep(string& x, string w, stringpar p) {
|
||||
rep(x, "%den"+w, "the");
|
||||
}
|
||||
}
|
||||
if(l == 6) {
|
||||
if(N) {
|
||||
rep(x, "%"+w, N->n[5].nom);
|
||||
rep(x, "%P"+w, N->n[5].nomp);
|
||||
rep(x, "%na"+w, choose4(N->n[5].genus, "o", "a", "os", "as") + " " + N->n[5].nom);
|
||||
rep(x, "%g"+w, choose4(N->n[5].genus, "do", "da", "dos", "das")+ " " + N->n[5].nom);
|
||||
rep(x, "%d"+w, choose4(N->n[5].genus, "ao", "à", "aos", "às")+ " " + N->n[5].nom);
|
||||
rep(x, "%l"+w, choose4(N->n[5].genus, "no", "na", "nos", "nas")+ " " + N->n[5].nom);
|
||||
rep(x, "%abl"+w, choose4(N->n[5].genus, "pelo", "pela", "pelos", "pelas")+ " " + N->n[5].nom);
|
||||
rep(x, "%seu"+w, choose4(N->n[5].genus, "seu", "sua", "seus", "suas"));
|
||||
}
|
||||
else {
|
||||
rep(x, "%"+w,p.v);
|
||||
rep(x, "%P"+w, p.v);
|
||||
rep(x, "%na"+w, p.v);
|
||||
rep(x, "%g"+w, p.v);
|
||||
rep(x, "%d"+w, p.v);
|
||||
rep(x, "%l"+w, p.v);
|
||||
rep(x, "%abl"+w, p.v);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(true) {
|
||||
// proper names (R'Lyeh)
|
||||
|
@ -21,7 +21,7 @@ namespace mapeditor {
|
||||
bool side;
|
||||
cell *c;
|
||||
} ew, ewsearch;
|
||||
bool autochoose;
|
||||
bool autochoose = ISMOBILE;
|
||||
|
||||
#if CAP_EDIT
|
||||
map<int, cell*> modelcell;
|
||||
@ -613,7 +613,7 @@ namespace mapeditor {
|
||||
}
|
||||
|
||||
void displayFunctionKeys() {
|
||||
int fs = vid.fsize + 5;
|
||||
int fs = min(vid.fsize + 5, vid.yres/26);
|
||||
displayButton(8, vid.yres-8-fs*11, XLAT("F1 = help"), SDLK_F1, 0);
|
||||
displayButton(8, vid.yres-8-fs*10, XLAT("F2 = save"), SDLK_F2, 0);
|
||||
displayButton(8, vid.yres-8-fs*9, XLAT("F3 = load"), SDLK_F3, 0);
|
||||
@ -621,7 +621,9 @@ namespace mapeditor {
|
||||
displayButton(8, vid.yres-8-fs*7, XLAT("F5 = restart"), SDLK_F5, 0);
|
||||
displayButton(8, vid.yres-8-fs*6, XLAT("F6 = HQ shot"), SDLK_F6, 0);
|
||||
displayButton(8, vid.yres-8-fs*5, XLAT("F7 = player on/off"), SDLK_F7, 0);
|
||||
#if CAP_SVG
|
||||
displayButton(8, vid.yres-8-fs*4, XLAT("F8 = SVG shot"), SDLK_F8, 0);
|
||||
#endif
|
||||
displayButton(8, vid.yres-8-fs*3, XLAT("SPACE = map/graphics"), ' ', 0);
|
||||
displayButton(8, vid.yres-8-fs*2, XLAT("ESC = return to the game"), SDLK_ESCAPE, 0);
|
||||
}
|
||||
@ -793,7 +795,7 @@ namespace mapeditor {
|
||||
cmode = sm::MAP;
|
||||
gamescreen(0);
|
||||
|
||||
int fs = vid.fsize + 5;
|
||||
int fs = min(vid.fsize + 5, vid.yres/26);
|
||||
|
||||
getcstat = '-';
|
||||
|
||||
@ -1130,7 +1132,7 @@ namespace mapeditor {
|
||||
|
||||
// left-clicks are coded with '-', and right-clicks are coded with sym F1
|
||||
if(uni == '-') undoLock();
|
||||
if(mousepressed && mouseover && sym != SDLK_F1)
|
||||
if(uni == '-' && mouseover)
|
||||
allInPattern(mouseover, radius, neighborId(mouseover, mouseover2));
|
||||
|
||||
if(mouseover) for(int i=0; i<mouseover->type; i++) createMov(mouseover, i);
|
||||
@ -1262,22 +1264,6 @@ namespace mapeditor {
|
||||
}
|
||||
}
|
||||
queueline(drawtrans*ccenter, drawtrans*coldcenter, darkena(0xC0C0C0, 0, 0x20));
|
||||
|
||||
int sg = drawcellShapeGroup();
|
||||
|
||||
if(0) for(int i=0; i<USERSHAPEIDS; i++) if(editingShape(sg, i) && usershapes[sg][i]) {
|
||||
|
||||
usershapelayer &ds(usershapes[sg][i]->d[mapeditor::dslayer]);
|
||||
|
||||
for(int a=0; a<size(ds.list); a++) {
|
||||
hyperpoint P2 = drawtrans * ds.list[a];
|
||||
|
||||
queuechr(P2, 10, 'x',
|
||||
darkena(a == 0 ? 0x00FF00 :
|
||||
a == size(ds.list)-1 ? 0xFF0000 :
|
||||
0xFFFF00, 0, 0xFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawHandleKey(int sym, int uni);
|
||||
@ -1323,7 +1309,7 @@ namespace mapeditor {
|
||||
|
||||
usershape *us =usershapes[drawcellShapeGroup()][drawcellShapeID()];
|
||||
|
||||
int fs = vid.fsize + 5;
|
||||
int fs = min(vid.fsize + 5, vid.yres/28);
|
||||
|
||||
// displayButton(8, 8+fs*9, XLAT("l = lands"), 'l', 0);
|
||||
displayfr(8, 8+fs, 2, vid.fsize, line1, 0xC0C0C0, 0);
|
||||
@ -1353,11 +1339,12 @@ namespace mapeditor {
|
||||
|
||||
}
|
||||
else {
|
||||
displayfr(8, 8+fs*5, 2, vid.fsize, XLAT("'n' to start"), 0xC0C0C0, 0);
|
||||
mousekey = 'n';
|
||||
displaymm('n', 8, 8+fs*5, 2, vid.fsize, XLAT("'n' to start"), 0);
|
||||
if(mousekey == 'a' || mousekey == 'd' || mousekey == 'd' ||
|
||||
mousekey == 'c') mousekey = 'n';
|
||||
}
|
||||
|
||||
displaymm('e', vid.xres-8, 8+fs*4, 2, vid.fsize, XLAT("g = grid"), 16);
|
||||
displaymm('g', vid.xres-8, 8+fs*4, 2, vid.fsize, XLAT("g = grid"), 16);
|
||||
displayButton(vid.xres-8, 8+fs*3, XLAT("z = zoom in"), 'z', 16);
|
||||
displayButton(vid.xres-8, 8+fs*2, XLAT("o = zoom out"), 'o', 16);
|
||||
displaymm('e', vid.xres-8, 8+fs, 2, vid.fsize, XLAT("e = edit this"), 16);
|
||||
@ -1580,7 +1567,7 @@ namespace mapeditor {
|
||||
for(int i=0; i<USERSHAPEIDS; i++) if(editingShape(sg, i))
|
||||
applyToShape(sg, i, uni, mh);
|
||||
|
||||
if(uni == 'e') {
|
||||
if(uni == 'e' || (uni == '-' && mousekey == 'e')) {
|
||||
initdraw(mouseover ? mouseover : cwt.c);
|
||||
}
|
||||
if(uni == 'l') { dslayer++; dslayer %= USERLAYERS; }
|
||||
@ -1701,10 +1688,12 @@ namespace mapeditor {
|
||||
saveHighQualityShot();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if CAP_SVG
|
||||
if(sym == SDLK_F8) {
|
||||
svg::render();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(sym == SDLK_F5) {
|
||||
for(int i=0; i<USERSHAPEGROUPS; i++)
|
||||
@ -1873,7 +1862,7 @@ namespace mapeditor {
|
||||
}
|
||||
|
||||
bool drawUserShape(transmatrix V, int group, int id, int color, cell *c) {
|
||||
#if ISMOBILE==1
|
||||
#if !CAP_EDIT
|
||||
return false;
|
||||
#else
|
||||
|
||||
@ -1888,7 +1877,6 @@ namespace mapeditor {
|
||||
}
|
||||
}
|
||||
|
||||
#if CAP_EDIT
|
||||
if((cmode & sm::DRAW) && mapeditor::editingShape(group, id)) {
|
||||
|
||||
/* for(int a=0; a<size(ds.list); a++) {
|
||||
@ -1985,7 +1973,6 @@ namespace mapeditor {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return us;
|
||||
#endif
|
||||
|
219
menus.cpp
219
menus.cpp
@ -520,55 +520,6 @@ void showChangeMode() {
|
||||
};
|
||||
}
|
||||
|
||||
// -- cheat menu --
|
||||
|
||||
void showCheatMenu() {
|
||||
gamescreen(1);
|
||||
dialog::init("cheat menu");
|
||||
dialog::addItem(XLAT("return to the game"), ' ');
|
||||
dialog::addBreak(50);
|
||||
dialog::addItem(XLAT("gain orb powers"), 'F');
|
||||
dialog::addItem(XLAT("summon treasure"), 'T');
|
||||
dialog::addItem(XLAT("summon dead orbs"), 'D');
|
||||
dialog::addItem(XLAT("lose all treasure"), 'J');
|
||||
dialog::addItem(XLAT("gain kills"), 'K');
|
||||
dialog::addItem(XLAT("Hyperstone Quest"), 'C');
|
||||
dialog::addItem(XLAT("summon orbs"), 'O');
|
||||
dialog::addItem(XLAT("gain Orb of Yendor"), 'Y');
|
||||
dialog::addItem(XLAT("summon lots of treasure"), 'T'-64);
|
||||
dialog::addItem(XLAT("Safety (quick save)"), 'S');
|
||||
dialog::addItem(XLAT("Select the land ---"), 'L');
|
||||
dialog::addItem(XLAT("--- and teleport there"), 'U');
|
||||
dialog::addItem(XLAT("rotate the character"), 'Z');
|
||||
dialog::addItem(XLAT("summon a Golem"), 'G');
|
||||
dialog::addItem(XLAT("summon Sandworm"), 'W');
|
||||
dialog::addItem(XLAT("summon Ivy"), 'I');
|
||||
dialog::addItem(XLAT("summon a Monster"), 'E');
|
||||
dialog::addItem(XLAT("summon Thumpers"), 'H');
|
||||
dialog::addItem(XLAT("summon Bonfire"), 'B');
|
||||
dialog::addItem(XLAT("summon Mimics"), 'M');
|
||||
dialog::addItem(XLAT("deplete orb powers"), 'P');
|
||||
dialog::addItem(XLAT("summon Orb of Yendor"), 'Y'-64);
|
||||
dialog::addItem(XLAT("switch ghost timer"), 'G'-64);
|
||||
dialog::addItem(XLAT("switch web display"), 'W'-64);
|
||||
dialog::display();
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(uni != 0) {
|
||||
applyCheat(uni);
|
||||
if(uni == 'F' || uni == 'C' || uni == 'O' ||
|
||||
uni == 'S' || uni == 'U' || uni == 'G' ||
|
||||
uni == 'W' || uni == 'I' || uni == 'E' ||
|
||||
uni == 'H' || uni == 'B' || uni == 'M' ||
|
||||
uni == 'P' || uni == 'Y'-64 || uni == 'G'-64 ||
|
||||
uni == ' ' || uni == 8 || uni == 13 ||
|
||||
uni == SDLK_ESCAPE || uni == 'q' || uni == 'v' || sym == SDLK_ESCAPE ||
|
||||
sym == SDLK_F10)
|
||||
popScreen();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// -- geometry menu --
|
||||
|
||||
int eupage = 0;
|
||||
@ -653,8 +604,8 @@ void showEuclideanMenu() {
|
||||
if(eupage * euperpage >= LAND_SPHEUC) eupage = 0;
|
||||
}
|
||||
else if(lid >= 0 && lid < LAND_SPHEUC) {
|
||||
euclidland = land_spheuc[lid];
|
||||
if(landvisited[euclidland] && euclidland != laOceanWall) {
|
||||
specialland = land_spheuc[lid];
|
||||
if(landvisited[specialland] && specialland != laOceanWall) {
|
||||
if(targetgeometry != geometry)
|
||||
restartGame('g');
|
||||
else
|
||||
@ -662,7 +613,7 @@ void showEuclideanMenu() {
|
||||
// disable PTM if chosen a land from the Euclidean menu
|
||||
if(tactic::on) restartGame('t');
|
||||
}
|
||||
else euclidland = laIce;
|
||||
else specialland = laIce;
|
||||
}
|
||||
else if(uni == '2' || sym == SDLK_F1) gotoHelp(
|
||||
"If you want to know how much the gameplay is affected by the "
|
||||
@ -725,42 +676,140 @@ void showDemo() {
|
||||
dialog::addItem(XLAT("Burial Grounds"), 'b');
|
||||
|
||||
dialog::display();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(sym == SDLK_F1 || sym == 'h') gotoHelp(help);
|
||||
else if(sym == 'a') {
|
||||
toggleanim(!demoanim);
|
||||
popScreen();
|
||||
}
|
||||
else if(sym == 'f') {
|
||||
firstland = laIce;
|
||||
if(tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
}
|
||||
else if(sym == 'T') {
|
||||
firstland = laIce;
|
||||
if(!tour::on) tour::start();
|
||||
}
|
||||
else if(sym == 't') {
|
||||
firstland = laTemple;
|
||||
if(!tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
}
|
||||
else if(sym == 'l') {
|
||||
firstland = laStorms;
|
||||
if(!tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
}
|
||||
else if(sym == 'b') {
|
||||
firstland = laBurial;
|
||||
if(!tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
items[itOrbSword] = 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleDemoKey(int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(sym == SDLK_F1 || sym == 'h') gotoHelp(help);
|
||||
else if(sym == 'a') {
|
||||
toggleanim(!demoanim);
|
||||
popScreen();
|
||||
}
|
||||
else if(sym == 'f') {
|
||||
firstland = laIce;
|
||||
if(tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
}
|
||||
else if(sym == 'T') {
|
||||
firstland = laIce;
|
||||
if(!tour::on) tour::start();
|
||||
}
|
||||
else if(sym == 't') {
|
||||
firstland = laTemple;
|
||||
if(!tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
}
|
||||
else if(sym == 'l') {
|
||||
firstland = laStorms;
|
||||
if(!tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
}
|
||||
else if(sym == 'b') {
|
||||
firstland = laBurial;
|
||||
if(!tactic::on) restartGame('t');
|
||||
else restartGame();
|
||||
items[itOrbSword] = 60;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool showstartmenu;
|
||||
|
||||
void showStartMenu() {
|
||||
gamescreen(2);
|
||||
|
||||
getcstat = ' ';
|
||||
|
||||
dialog::init();
|
||||
|
||||
dialog::addInfo(XLAT("Welcome to HyperRogue!"));
|
||||
dialog::addBreak(100);
|
||||
|
||||
dialog::addBigItem(XLAT("HyperRogue classic"), 'c');
|
||||
dialog::addInfo(XLAT("explore the world, collect treasures"));
|
||||
dialog::addInfo(XLAT("do not get checkmated"));
|
||||
|
||||
#if CAP_INV
|
||||
dialog::addBreak(100);
|
||||
dialog::addBigItem(XLAT("Orb Strategy mode"), 'i');
|
||||
dialog::addInfo(XLAT("use your Orbs in tough situations"));
|
||||
#endif
|
||||
|
||||
#if CAP_SHMUP
|
||||
dialog::addBreak(100);
|
||||
dialog::addBigItem(XLAT("shoot'em up mode"), 's');
|
||||
dialog::addInfo(XLAT("continuous spacetime"));
|
||||
#if HAVE_ACHIEVEMENTS
|
||||
dialog::addInfo(XLAT("(most achievements are not available)"));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CAP_TOUR
|
||||
dialog::addBreak(100);
|
||||
dialog::addBigItem(XLAT("tutorial"), 't');
|
||||
dialog::addInfo(XLAT("learn about hyperbolic geometry!"));
|
||||
#endif
|
||||
|
||||
#if CAP_ROGUEVIZ && CAP_TOUR
|
||||
dialog::addBreak(100);
|
||||
dialog::addBigItem(XLAT("RogueViz"), 'r');
|
||||
dialog::addInfo(XLAT("see the visualizations"));
|
||||
#endif
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addBigItem(XLAT("main menu"), 'm');
|
||||
dialog::addInfo(XLAT("more options"));
|
||||
|
||||
dialog::display();
|
||||
clearMessages();
|
||||
|
||||
/*
|
||||
initquickqueue();
|
||||
int siz = min(vid.xres, vid.yres) / 8;
|
||||
drawMonsterType(moPrincess, NULL, atscreenpos(siz,siz,siz) * spin(-M_PI/4), 0, 0);
|
||||
drawMonsterType(moKnight, NULL, atscreenpos(vid.xres-siz,siz,siz) * spin(-3*M_PI/4), 0, 0);
|
||||
drawItemType(itOrbYendor, NULL, atscreenpos(siz,vid.yres-siz,siz) * spin(M_PI/4), iinf[itOrbYendor].color, 0, false);
|
||||
drawItemType(itKey, NULL, atscreenpos(siz,vid.yres-siz,siz) * spin(M_PI/4), iinf[itKey].color, 0, false);
|
||||
drawItemType(itHyperstone, NULL, atscreenpos(vid.xres-siz,vid.yres-siz,siz) * spin(3*M_PI/4), iinf[itHyperstone].color, 0, false);
|
||||
quickqueue();
|
||||
*/
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(uni == 'o') uni = 'i';
|
||||
if(uni == 'c' || uni == 'i' || uni == 's') {
|
||||
popScreenAll();
|
||||
if(inv::on != (uni == 'i')) restartGame('i');
|
||||
if(shmup::on != (uni == 's')) restartGame('S');
|
||||
clearMessages();
|
||||
welcomeMessage();
|
||||
}
|
||||
#if CAP_TOUR
|
||||
else if(uni == 't') {
|
||||
popScreenAll();
|
||||
tour::start();
|
||||
}
|
||||
#endif
|
||||
#if CAP_ROGUEVIZ && CAP_TOUR
|
||||
else if(uni == 'r') {
|
||||
tour::slides = rvtour::rvslides;
|
||||
popScreenAll();
|
||||
tour::start();
|
||||
}
|
||||
#endif
|
||||
else if(sym == 'm') {
|
||||
popScreen();
|
||||
pushScreen(showMainMenu);
|
||||
}
|
||||
else if(sym == SDLK_F10)
|
||||
quitmainloop = true;
|
||||
else if(sym == SDLK_F1)
|
||||
gotoHelp(help);
|
||||
else if(sym == SDLK_ESCAPE || sym == ' ')
|
||||
popScreen();
|
||||
};
|
||||
}
|
||||
|
||||
// -- overview --
|
||||
|
||||
|
2
quit.cpp
2
quit.cpp
@ -273,7 +273,7 @@ hint hints[] = {
|
||||
},
|
||||
[] () {
|
||||
if(!sphere) {
|
||||
euclidland = laHalloween;
|
||||
specialland = laHalloween;
|
||||
targetgeometry = gSphere;
|
||||
restartGame('E');
|
||||
vid.alpha = 999;
|
||||
|
10
rogueviz.cpp
10
rogueviz.cpp
@ -1343,11 +1343,11 @@ void init() {
|
||||
autocheat = true;
|
||||
#if !ISWEB
|
||||
mapeditor::drawplayer = false;
|
||||
firstland = euclidland = laCanvas;
|
||||
firstland = specialland = laCanvas;
|
||||
if(!shmup::on) restartGame('s');
|
||||
else restartGame();
|
||||
#else
|
||||
firstland = euclidland = laCanvas;
|
||||
firstland = specialland = laCanvas;
|
||||
restartGame();
|
||||
#endif
|
||||
on = true;
|
||||
@ -1849,11 +1849,11 @@ slide rvslides[] = {
|
||||
,
|
||||
[] (presmode mode) {
|
||||
slidecommand = "the standard presentation";
|
||||
if(mode == pmStartAll) firstland = euclidland = laPalace;
|
||||
if(mode == pmStartAll) firstland = specialland = laPalace;
|
||||
if(mode == 4) {
|
||||
tour::slides = default_slides;
|
||||
while(tour::on) restartGame('T', false);
|
||||
firstland = euclidland = laIce;
|
||||
firstland = specialland = laIce;
|
||||
tour::start();
|
||||
}
|
||||
}
|
||||
@ -1976,7 +1976,7 @@ slide rvslides[] = {
|
||||
{"THE END", 99, LEGAL_ANY | FINALSLIDE,
|
||||
"Press '5' to leave the presentation.",
|
||||
[] (presmode mode) {
|
||||
firstland = euclidland = laIce;
|
||||
firstland = specialland = laIce;
|
||||
if(mode == 4) restartGame('T');
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ int modediff(score *S) {
|
||||
if(S->box[196] != chaosmode) diff += 32;
|
||||
if(S->box[119] != shmup::on) diff += 64;
|
||||
if(pureHardcore() && !isHardcore(S)) diff += 128;
|
||||
if(g != gNormal && S->box[120] != euclidland)
|
||||
if(g != gNormal && S->box[120] != specialland)
|
||||
diff += 256;
|
||||
if(g != geometry) {
|
||||
diff += 512;
|
||||
|
444
system.cpp
444
system.cpp
@ -23,6 +23,60 @@ bool verless(string v, string cmp) {
|
||||
return v < cmp;
|
||||
}
|
||||
|
||||
void welcomeMessage() {
|
||||
if(tactic::trailer) return;
|
||||
#if CAP_TOUR
|
||||
else if(tour::on) return; // displayed by tour
|
||||
#endif
|
||||
else if(princess::challenge) {
|
||||
kills[moVizier] = 1;
|
||||
princess::forceMouse = true;
|
||||
if(yendor::everwon)
|
||||
items[itGreenStone] = 99;
|
||||
addMessage(XLAT("Welcome to %the1 Challenge!", moPrincess));
|
||||
addMessage(XLAT("The more Hypersian Rugs you collect, the harder it is.", moPrincess));
|
||||
}
|
||||
/* if(tactic::on && isCrossroads(firstland)) {
|
||||
for(int i=0; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_TREASURE && i != itHyperstone)
|
||||
items[i] = 10;
|
||||
kills[moYeti] = 1000;
|
||||
} */
|
||||
|
||||
else if(randomPatternsMode)
|
||||
addMessage(XLAT("Welcome to the Random Pattern mode!"));
|
||||
else if(tactic::on)
|
||||
addMessage(XLAT("You are playing %the1 in the Pure Tactics mode.", firstland));
|
||||
else if(yendor::on)
|
||||
addMessage(XLAT("Welcome to the Yendor Challenge %1!", its(yendor::challenge)));
|
||||
else if(peace::on) ; // no welcome message
|
||||
else if(shmup::on) ; // welcome message given elsewhere
|
||||
else if(euclid)
|
||||
addMessage(XLAT("Welcome to the Euclidean mode!"));
|
||||
else if(sphere && specialland == laHalloween)
|
||||
addMessage(XLAT("Welcome to Halloween!"));
|
||||
else if(elliptic)
|
||||
addMessage(XLAT("Good luck in the elliptic plane!"));
|
||||
else if(sphere)
|
||||
addMessage(XLAT("Welcome to Spherogue!"));
|
||||
#if CAP_ROGUEVIZ
|
||||
else if(rogueviz::on)
|
||||
addMessage(XLAT("Welcome to RogueViz!"));
|
||||
#endif
|
||||
else {
|
||||
addMessage(XLAT("Welcome to HyperRogue!"));
|
||||
}
|
||||
|
||||
if(shmup::on && (specialland == laMirror || specialland == laMirrorOld) && (geometry == gElliptic || geometry == gQuotient))
|
||||
addMessage(XLAT("This combination is known to be buggy at the moment."));
|
||||
|
||||
#if ISMAC
|
||||
addMessage(XLAT("Press F1 or right-shift-click things for help."));
|
||||
#elif !ISMOBILE
|
||||
addMessage(XLAT("Press F1 or right-click things for help."));
|
||||
#endif
|
||||
}
|
||||
|
||||
// initialize the game
|
||||
void initgame() {
|
||||
DEBB(DF_INIT, (debugfile,"initGame\n"));
|
||||
@ -34,9 +88,9 @@ void initgame() {
|
||||
firstland = safetyland;
|
||||
}
|
||||
|
||||
if(peace::on) euclidland = firstland = peace::whichland;
|
||||
if(peace::on) firstland = specialland;
|
||||
|
||||
if(tactic::on && (euclid || sphere)) euclidland = firstland;
|
||||
if(tactic::on && (euclid || sphere)) specialland = firstland;
|
||||
|
||||
if(firstland == laNone || firstland == laBarrier)
|
||||
firstland = laCrossroads;
|
||||
@ -48,7 +102,7 @@ void initgame() {
|
||||
if(isGravityLand(firstland) && !tactic::on) firstland = laCrossroads;
|
||||
|
||||
cwt.c = currentmap->gamestart(); cwt.spin = 0; cwt.mirrored = false;
|
||||
cwt.c->land = (euclid || sphere) ? euclidland : firstland;
|
||||
cwt.c->land = (euclid || sphere) ? specialland : firstland;
|
||||
|
||||
chaosAchieved = false;
|
||||
|
||||
@ -92,7 +146,7 @@ void initgame() {
|
||||
|
||||
for(int i=0; i<65536; i++) euland[i] = laNone;
|
||||
|
||||
if(euclid && euclidland == laPrincessQuest) {
|
||||
if(euclid && specialland == laPrincessQuest) {
|
||||
cell *c = euclideanAtCreate(EPX, EPY);
|
||||
princess::generating = true;
|
||||
c->land = laPalace;
|
||||
@ -198,56 +252,7 @@ void initgame() {
|
||||
if(!randomPatternsMode && !tactic::on && !yendor::on && !peace::on) {
|
||||
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
|
||||
}
|
||||
if(tactic::trailer) ;
|
||||
#if CAP_TOUR
|
||||
else if(tour::on) ; // displayed by tour
|
||||
#endif
|
||||
else if(princess::challenge) {
|
||||
kills[moVizier] = 1;
|
||||
princess::forceMouse = true;
|
||||
if(yendor::everwon)
|
||||
items[itGreenStone] = 99;
|
||||
addMessage(XLAT("Welcome to %the1 Challenge!", moPrincess));
|
||||
addMessage(XLAT("The more Hypersian Rugs you collect, the harder it is.", moPrincess));
|
||||
}
|
||||
/* if(tactic::on && isCrossroads(firstland)) {
|
||||
for(int i=0; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_TREASURE && i != itHyperstone)
|
||||
items[i] = 10;
|
||||
kills[moYeti] = 1000;
|
||||
} */
|
||||
|
||||
else if(randomPatternsMode)
|
||||
addMessage(XLAT("Welcome to the Random Pattern mode!"));
|
||||
else if(tactic::on)
|
||||
addMessage(XLAT("You are playing %the1 in the Pure Tactics mode.", firstland));
|
||||
else if(yendor::on)
|
||||
addMessage(XLAT("Welcome to the Yendor Challenge %1!", its(yendor::challenge)));
|
||||
else if(peace::on) ; // no welcome message
|
||||
else if(shmup::on) ; // welcome message given elsewhere
|
||||
else if(euclid)
|
||||
addMessage(XLAT("Welcome to the Euclidean mode!"));
|
||||
else if(sphere && euclidland == laHalloween)
|
||||
addMessage(XLAT("Welcome to Halloween!"));
|
||||
else if(elliptic)
|
||||
addMessage(XLAT("Good luck in the elliptic plane!"));
|
||||
else if(sphere)
|
||||
addMessage(XLAT("Welcome to Spherogue!"));
|
||||
#if CAP_ROGUEVIZ
|
||||
else if(rogueviz::on)
|
||||
addMessage(XLAT("Welcome to RogueViz!"));
|
||||
#endif
|
||||
else {
|
||||
addMessage(XLAT("Welcome to HyperRogue!"));
|
||||
#if ISMAC
|
||||
addMessage(XLAT("Press F1 or right-shift-click things for help."));
|
||||
#elif !ISMOBILE
|
||||
addMessage(XLAT("Press F1 or right-click things for help."));
|
||||
#endif
|
||||
}
|
||||
|
||||
if(shmup::on && (euclidland == laMirror || euclidland == laMirrorOld) && (geometry == gElliptic || geometry == gQuotient))
|
||||
addMessage(XLAT("This combination is known to be buggy at the moment."));
|
||||
welcomeMessage();
|
||||
}
|
||||
else {
|
||||
usedSafety = true;
|
||||
@ -456,8 +461,8 @@ void applyBoxes() {
|
||||
applyBoxBool(hardcore, "hardcore");
|
||||
applyBoxNum(hardcoreAt, "");
|
||||
applyBoxBool(shmup::on, "shmup");
|
||||
if(saving) applyBoxSave(euclidland, "euclid land");
|
||||
else if(loading) euclidland = eLand(applyBoxLoad("euclid land"));
|
||||
if(saving) applyBoxSave(specialland, "euclid land");
|
||||
else if(loading) specialland = eLand(applyBoxLoad("euclid land"));
|
||||
else fakebox[boxid++] = true;
|
||||
|
||||
applyBoxI(itCoast);
|
||||
@ -931,6 +936,13 @@ void loadsave() {
|
||||
safety = true;
|
||||
if(items[itSavedPrincess] < 0) items[itSavedPrincess] = 0;
|
||||
addMessage(XLAT("Game loaded."));
|
||||
showstartmenu = false;
|
||||
// reset unsavable special modes just in case
|
||||
peace::on = false;
|
||||
randomPatternsMode = false;
|
||||
yendor::on = false;
|
||||
tactic::on = false;
|
||||
tour::on = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1133,326 +1145,6 @@ void restartGame(char switchWhat, bool push) {
|
||||
resetmusic();
|
||||
}
|
||||
|
||||
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(hrand(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; a<ittypes; a++) {
|
||||
eItem i = eItem(a);
|
||||
if(itemclass(i) != IC_TREASURE) continue;
|
||||
int q = 2*items[i];
|
||||
if(a == lt) q -= (2*cv-1);
|
||||
if(a == itEmerald && bearsCamelot(cwt.c->land)) q -= 8;
|
||||
if(a == itElixir && isCrossroads(cwt.c->land)) q -= 7;
|
||||
if(a == itIvory && isCrossroads(cwt.c->land)) q -= 6;
|
||||
if(a == itPalace && isCrossroads(cwt.c->land)) q -= 5;
|
||||
if(a == itIvory && cwt.c->land == laJungle) q -= 5;
|
||||
if(a == itIvory && cwt.c->land == laPalace) q -= 5;
|
||||
if(q < bq) bq = q, cq = 0;
|
||||
if(q == bq) { cq++; if(hrand(cq) == 0) best = i; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
bool isTechnicalLand(eLand l) {
|
||||
return l == laNone || l == laOceanWall || l == laBarrier || l == laCanvas ||
|
||||
l == laHauntedWall || l == laHauntedBorder || l == laCA ||
|
||||
l == laMirrorWall || l == laMirrored;
|
||||
}
|
||||
|
||||
eLand cheatdest;
|
||||
|
||||
void cheatMoveTo(eLand l) {
|
||||
cheatdest = l;
|
||||
if(l == laCrossroads5) l = laCrossroads;
|
||||
activateSafety(l);
|
||||
cheatdest = laNone;
|
||||
}
|
||||
|
||||
bool applyCheat(char u, cell *c = NULL) {
|
||||
|
||||
if(u == 'G') {
|
||||
addMessage(XLAT("You summon a golem!"));
|
||||
cheater++;
|
||||
int i = cwt.spin;
|
||||
if(passable(cwt.c->mov[i], NULL, 0))
|
||||
cwt.c->mov[i]->monst = hrand(2) ? moGolem : moTameBomberbird;
|
||||
return true;
|
||||
}
|
||||
if(u == 'L') {
|
||||
do {
|
||||
if(firstland == eLand(landtypes-1))
|
||||
firstland = eLand(2);
|
||||
else
|
||||
firstland = eLand(firstland+1);
|
||||
}
|
||||
while(isTechnicalLand(firstland) || isCyclic(firstland));
|
||||
euclidland = firstland;
|
||||
cheater++; addMessage(XLAT("You will now start your games in %1", firstland));
|
||||
return true;
|
||||
}
|
||||
if(u == 'C') {
|
||||
cheater++;
|
||||
cheatMoveTo(laCrossroads);
|
||||
addMessage(XLAT("Activated the Hyperstone Quest!"));
|
||||
|
||||
for(int t=1; t<ittypes; t++)
|
||||
if(t != itHyperstone && t != itBounty && itemclass(eItem(t)) == IC_TREASURE) {
|
||||
items[t] = 10;
|
||||
}
|
||||
kills[moYeti] = 200;
|
||||
kills[moDesertman] = 200;
|
||||
kills[moRunDog] = 200;
|
||||
kills[moZombie] = 200;
|
||||
kills[moMonkey] = 200;
|
||||
kills[moCultist] = 200;
|
||||
kills[moTroll] = 200;
|
||||
return true;
|
||||
}
|
||||
if(u == 'P') {
|
||||
for(int i=0; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_ORB)
|
||||
items[i] = 0;
|
||||
cheater++; addMessage(XLAT("Orb power depleted!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'O') {
|
||||
cheater++; addMessage(XLAT("Orbs summoned!"));
|
||||
for(int i=0; i<cwt.c->type; i++)
|
||||
if(passable(cwt.c->mov[i], NULL, 0)) {
|
||||
eItem it = nextOrb();
|
||||
cwt.c->mov[i]->item = it;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'F') {
|
||||
if(hardcore && !canmove) {
|
||||
canmove = true;
|
||||
addMessage(XLAT("Revived!"));
|
||||
}
|
||||
else {
|
||||
items[itOrbFlash] += 1;
|
||||
items[itOrbTeleport] += 1;
|
||||
items[itOrbLightning] += 1;
|
||||
items[itOrbSpeed] += 1;
|
||||
items[itOrbShield] += 1;
|
||||
cheater++; addMessage(XLAT("Orb power gained!"));
|
||||
canmove = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'D') {
|
||||
items[itGreenStone] += 10;
|
||||
cheater++; addMessage(XLAT("Dead orbs gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'R'-64) buildRosemap();
|
||||
#if CAP_EDIT
|
||||
if(u == 'A') {
|
||||
lastexplore = turncount;
|
||||
pushScreen(mapeditor::showMapEditor);
|
||||
return true;
|
||||
}
|
||||
if(u == 'A'-64) {
|
||||
mapeditor::drawcell = mouseover ? mouseover : cwt.c;
|
||||
pushScreen(mapeditor::showDrawEditor);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
if(u == 'Y') {
|
||||
items[itOrbYendor] ++;
|
||||
cheater++; addMessage(XLAT("Orb of Yendor gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'T') {
|
||||
items[randomTreasure2(10)] += 10;
|
||||
cheater++; addMessage(XLAT("Treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'T'-64) {
|
||||
items[randomTreasure2(100)] += 100;
|
||||
cheater++; addMessage(XLAT("Lots of treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'I'-64) {
|
||||
items[randomTreasure2(10)] += 25;
|
||||
cheater++; addMessage(XLAT("Treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'U'-64) {
|
||||
items[randomTreasure2(10)] += 50;
|
||||
cheater++; addMessage(XLAT("Treasure gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'W') {
|
||||
addMessage(XLAT("You summon a sandworm!"));
|
||||
cheater++;
|
||||
int i = cwt.spin;
|
||||
if(passable(cwt.c->mov[i], NULL, 0))
|
||||
cwt.c->mov[i]->monst = moWorm,
|
||||
cwt.c->mov[i]->mondir = NODIR;
|
||||
return true;
|
||||
}
|
||||
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, 0)) buildIvy(c, 0, 1);
|
||||
return true;
|
||||
}
|
||||
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, P_MONSTER)) {
|
||||
eMonster mo[9] = { moEagle, moPyroCultist, moGhost, moTroll, moMiner, moVineBeast, moBug0,
|
||||
moBomberbird, moSkeleton };
|
||||
cwt.c->mov[i]->monst = mo[hrand(9)];
|
||||
cwt.c->mov[i]->stuntime = 3;
|
||||
cwt.c->mov[i]->hitpoints = 3;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'E'-64) {
|
||||
if(geometry) {
|
||||
restartGame(0, false);
|
||||
}
|
||||
else {
|
||||
euclidland = cwt.c->land;
|
||||
printf("target geometry = %d\n", targetgeometry);
|
||||
restartGame('g', true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'H') {
|
||||
addMessage(XLAT("You summon some Thumpers!"));
|
||||
cheater++;
|
||||
for(int i=0; i<cwt.c->type; i++)
|
||||
if(passable(cwt.c->mov[i], NULL, 0)) {
|
||||
eWall ws[3] = { waThumperOff, waBigStatue, waBoat };
|
||||
cwt.c->mov[i]->wall = ws[hrand(3)];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(u == 'B') {
|
||||
addMessage(XLAT("You summon a bonfire!"));
|
||||
cheater++;
|
||||
int i = cwt.spin;
|
||||
if(passable(cwt.c->mov[i], NULL, 0))
|
||||
cwt.c->mov[i]->wall = waBonfireOff;
|
||||
return true;
|
||||
}
|
||||
if(u == 'Z') {
|
||||
flipplayer = false;
|
||||
mirror::act(1, mirror::SPINSINGLE);
|
||||
cwspin(cwt, 1);
|
||||
return true;
|
||||
}
|
||||
if(u == 'J') {
|
||||
if(items[localTreasureType()] > 0)
|
||||
items[localTreasureType()] = 0;
|
||||
else for(int i=1; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_TREASURE)
|
||||
items[i] = 0;
|
||||
cheater++; addMessage(XLAT("Treasure lost!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'K') {
|
||||
for(int i=0; i<motypes; i++) kills[i] += 10;
|
||||
kills[moPlayer] = 0;
|
||||
cheater++; addMessage(XLAT("Kills gained!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'S') {
|
||||
canmove = true;
|
||||
cheatMoveTo(cwt.c->land);
|
||||
items[itOrbSafety] += 3;
|
||||
cheater++; addMessage(XLAT("Activated Orb of Safety!"));
|
||||
return true;
|
||||
}
|
||||
if(u == 'U') {
|
||||
canmove = true;
|
||||
cheatMoveTo(firstland);
|
||||
cheater++; addMessage(XLAT("Teleported to %1!", firstland));
|
||||
return true;
|
||||
}
|
||||
if(u == 'W'-64) {
|
||||
pushScreen(linepatterns::showMenu);
|
||||
return true;
|
||||
}
|
||||
if(u == 'G'-64) {
|
||||
timerghost = !timerghost;
|
||||
cheater++;
|
||||
addMessage(XLAT("turn count = %1 last exploration = %2 ghost timer = %3",
|
||||
its(turncount), its(lastexplore), ONOFF(timerghost)));
|
||||
return true;
|
||||
}
|
||||
if(u == 'F'-64) {
|
||||
items[itOrbShield] += 30;
|
||||
return true;
|
||||
}
|
||||
if(u == 'Y'-64) {
|
||||
int i = cwt.spin;
|
||||
cwt.c->mov[i]->item = itOrbYendor;
|
||||
return true;
|
||||
}
|
||||
if(u == 'B'-64) {
|
||||
int i = cwt.spin;
|
||||
sword::angle[0]++;
|
||||
cwt.c->mov[i]->item = hrand(2) ? itOrbSword2 : itOrbSword;
|
||||
return true;
|
||||
}
|
||||
if(u == 'X'-64) {
|
||||
items[itOrbNature] += 50;
|
||||
cheater++;
|
||||
return true;
|
||||
}
|
||||
if(u == 'V'-64) {
|
||||
viewdists = !viewdists;
|
||||
return true;
|
||||
}
|
||||
if(u == 'L'-64) {
|
||||
cell *c = mouseover;
|
||||
describeCell(c);
|
||||
printf("Neighbors:"); for(int i=0; i<c->type; i++) printf("%p ", c->mov[i]);
|
||||
printf("Barrier: dir=%d left=%d right=%d\n",
|
||||
c->bardir, c->barleft, c->barright);
|
||||
return true;
|
||||
}
|
||||
if(u == 'C'-64) {
|
||||
cblind = !cblind;
|
||||
return true;
|
||||
}
|
||||
if(u == 'P'-64)
|
||||
peace::on = !peace::on;
|
||||
#ifdef CHEAT_DISABLE_ALLOWED
|
||||
if(u == 'D'-64) {
|
||||
cheater = 0; autocheat = 0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
purehookset clearmemory;
|
||||
|
||||
void clearMemory() {
|
||||
|
25
tour.cpp
25
tour.cpp
@ -150,7 +150,7 @@ bool handleKeyTour(int sym, int uni) {
|
||||
|
||||
if(sym == '1') targetgeometry = gSphere;
|
||||
if(sym == '2') targetgeometry = gEuclid;
|
||||
firstland = euclidland = cwt.c->land;
|
||||
firstland = specialland = cwt.c->land;
|
||||
restartGame(sym == '3' ? '7' : 'g', true);
|
||||
presentation(pmGeometryStart);
|
||||
return true;
|
||||
@ -289,7 +289,7 @@ void start() {
|
||||
if(!tour::on) presentation(pmStartAll);
|
||||
else {
|
||||
presentation(pmStop);
|
||||
firstland = euclidland = laIce;
|
||||
firstland = specialland = laIce;
|
||||
}
|
||||
restartGame('T');
|
||||
if(tour::on) {
|
||||
@ -299,6 +299,25 @@ void start() {
|
||||
}
|
||||
|
||||
slide default_slides[] = {
|
||||
#if ISMOBILE
|
||||
{"Note for mobiles", 10, LEGAL_ANY | QUICKSKIP,
|
||||
"This tutorial is designed for computers, "
|
||||
"and keys are given for all actions. It will "
|
||||
"work without a keyboard though, although less "
|
||||
"comfortably -- just ignore the keys "
|
||||
"given and select options from MENU.\n\n"
|
||||
"Select 'next slide' from MENU.",
|
||||
|
||||
[] (presmode mode) {
|
||||
if(mode == pmStartAll) firstland = specialland = laIce;
|
||||
if(mode == 1) {
|
||||
if(tour::texts) addMessage(XLAT("Welcome to the HyperRogue tutorial!"));
|
||||
else clearMessages();
|
||||
}
|
||||
SHOWLAND( l == laIce );
|
||||
}
|
||||
},
|
||||
#endif
|
||||
{"Introduction", 10, LEGAL_ANY | QUICKSKIP,
|
||||
"This tutorial is mostly aimed to show what is "
|
||||
"special about the geometry used by HyperRogue. "
|
||||
@ -309,7 +328,7 @@ slide default_slides[] = {
|
||||
"press ESC to see a "
|
||||
"menu with other options.",
|
||||
[] (presmode mode) {
|
||||
if(mode == pmStartAll) firstland = euclidland = laIce;
|
||||
if(mode == pmStartAll) firstland = specialland = laIce;
|
||||
if(mode == 1) {
|
||||
if(tour::texts) addMessage(XLAT("Welcome to the HyperRogue tutorial!"));
|
||||
else clearMessages();
|
||||
|
4
util.cpp
4
util.cpp
@ -3,7 +3,7 @@
|
||||
|
||||
// basic utility functions
|
||||
|
||||
#if ISMOBILE || ISWEB || ISPANDORA
|
||||
#if ISMOBILE || ISWEB || ISPANDORA || 1
|
||||
typedef double ld;
|
||||
#define LDF "%lf"
|
||||
#define PLDF "lf"
|
||||
@ -36,6 +36,8 @@ string llts(long long i) {
|
||||
return llts(i/10) + its(i%10);
|
||||
}
|
||||
string itsh(int i) {static char buf[16]; sprintf(buf, "%03X", i); return buf; }
|
||||
string itsh2(int i) {static char buf[16]; sprintf(buf, "%02X", i); return buf; }
|
||||
string itsh8(int i) {static char buf[16]; sprintf(buf, "%08X", i); return buf; }
|
||||
|
||||
// debug utilities
|
||||
|
||||
|
38
yendor.cpp
38
yendor.cpp
@ -52,7 +52,7 @@ namespace yendor {
|
||||
int challenge; // id of the challenge
|
||||
int lastchallenge;
|
||||
|
||||
#define YENDORLEVELS 29
|
||||
#define YENDORLEVELS 30
|
||||
|
||||
int bestscore[MODECODES][YENDORLEVELS];
|
||||
|
||||
@ -72,6 +72,7 @@ namespace yendor {
|
||||
#define YF_START_CR 4096
|
||||
#define YF_CHAOS 8192
|
||||
#define YF_RECALL 16384
|
||||
#define YF_NEAR_FJORD 32768
|
||||
|
||||
#define YF_START_ANY (YF_START_AL|YF_START_CR)
|
||||
|
||||
@ -109,6 +110,7 @@ namespace yendor {
|
||||
{laDragon, YF_DEAD},
|
||||
{laReptile, 0},
|
||||
{laTortoise, YF_RECALL},
|
||||
{laCocytus, YF_NEAR_FJORD}
|
||||
};
|
||||
|
||||
int tscorelast;
|
||||
@ -145,6 +147,8 @@ namespace yendor {
|
||||
bool found;
|
||||
bool foundOrb;
|
||||
int howfar;
|
||||
cell* key() { return path[YDIST-1]; }
|
||||
cell* orb() { return path[0]; }
|
||||
};
|
||||
|
||||
vector<yendorinfo> yi;
|
||||
@ -324,7 +328,7 @@ namespace yendor {
|
||||
won = false;
|
||||
if(!easy) items[itOrbYendor] = bestscore[modecode()][challenge];
|
||||
chaosmode = (clev().flags & YF_CHAOS);
|
||||
euclidland = firstland = clev().l;
|
||||
specialland = firstland = clev().l;
|
||||
if(clev().flags & YF_START_AL) {
|
||||
firstland = laAlchemist;
|
||||
items[itElixir] = 50;
|
||||
@ -337,6 +341,7 @@ namespace yendor {
|
||||
}
|
||||
if(firstland == laGraveyard) items[itBone] = 10;
|
||||
if(firstland == laEmerald) items[itEmerald] = 10;
|
||||
if(firstland == laCocytus) items[itFjord] = 10;
|
||||
if(!euclid) {
|
||||
if(clev().flags & YF_DEAD) items[itGreenStone] = 100;
|
||||
if(clev().flags & YF_DEAD5) items[itGreenStone] = 5;
|
||||
@ -361,6 +366,8 @@ namespace yendor {
|
||||
yendor::check(c2);
|
||||
if(clev().flags & YF_NEAR_IVY)
|
||||
nexttostart = laJungle;
|
||||
if(clev().flags & YF_NEAR_FJORD)
|
||||
nexttostart = laLivefjord;
|
||||
if(clev().flags & YF_NEAR_TENT)
|
||||
nexttostart = laRlyeh;
|
||||
if(clev().flags & YF_NEAR_ELEM) {
|
||||
@ -404,6 +411,7 @@ namespace yendor {
|
||||
if((ylev.flags & YF_NEAR_RED) && hiitemsMax(itRedGem) < 10) return false;
|
||||
if((ylev.flags & YF_NEAR_OVER) && hiitemsMax(itMutant) < 10) return false;
|
||||
if((ylev.flags & YF_NEAR_TENT) && hiitemsMax(itStatue) < 10) return false;
|
||||
if((ylev.flags & YF_NEAR_FJORD) && hiitemsMax(itFjord) < 10) return false;
|
||||
if((ylev.flags & YF_CHAOS) && !chaosUnlocked) return false;
|
||||
if((ylev.flags & (YF_DEAD|YF_DEAD5)) && hiitemsMax(itBone) < 10) return false;
|
||||
if((ylev.flags & YF_RECALL) && hiitemsMax(itSlime) < 10) return false;
|
||||
@ -457,6 +465,7 @@ namespace yendor {
|
||||
if(!euclid) {
|
||||
if(ylev.flags & YF_CHAOS) { s = "Chaos mode"; }
|
||||
if(ylev.flags & YF_NEAR_IVY) { s += "+"; s += XLATT1(laJungle); }
|
||||
if(ylev.flags & YF_NEAR_FJORD) { s += "+"; s += XLATT1(laLivefjord); }
|
||||
if(ylev.flags & YF_NEAR_TENT) { s += "+"; s += XLATT1(laRlyeh); }
|
||||
if(ylev.flags & YF_NEAR_ELEM) { s += "+"; s += XLATT1(laElementalWall); }
|
||||
if(ylev.flags & YF_NEAR_OVER) { s += "+"; s += XLATT1(laOvergrown); }
|
||||
@ -744,7 +753,7 @@ namespace tactic {
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
if(uni >= 1000 && uni < 1000 + LAND_TAC) {
|
||||
firstland = euclidland = getLandById(uni - 1000);
|
||||
firstland = specialland = getLandById(uni - 1000);
|
||||
restartGame(tactic::on ? 0 : 't');
|
||||
}
|
||||
else if(uni == '0') {
|
||||
@ -911,7 +920,6 @@ namespace peace {
|
||||
bool hint = false;
|
||||
|
||||
bool otherpuzzles;
|
||||
eLand whichland;
|
||||
|
||||
eLand simonlevels[] = {
|
||||
laCrossroads, laCrossroads2, laDesert, laCaves, laAlchemist, laRlyeh, laEmerald,
|
||||
@ -931,8 +939,15 @@ namespace peace {
|
||||
eLand *levellist;
|
||||
int qty;
|
||||
|
||||
void listLevels() {
|
||||
levellist = otherpuzzles ? explorelevels : simonlevels;
|
||||
|
||||
for(qty = 0; levellist[qty]; qty++);
|
||||
}
|
||||
|
||||
eLand getNext(eLand last) {
|
||||
if(!peace::on) return laNone;
|
||||
if(!qty) listLevels();
|
||||
if(isElemental(last) && hrand(100) < 90)
|
||||
return laNone;
|
||||
else if(createOnSea(last))
|
||||
@ -985,10 +1000,10 @@ namespace peace {
|
||||
setdist(c, 5, NULL);
|
||||
|
||||
forCellEx(c2,c)
|
||||
if(!eq(c2->aitmp, sval) && passable(c2, c, 0) && (c2->land == whichland || c2->land == laTemple) && !c2->item) {
|
||||
if(!eq(c2->aitmp, sval) && passable(c2, c, 0) && (c2->land == specialland || c2->land == laTemple) && !c2->item) {
|
||||
if(!id) fr = c2;
|
||||
bool next;
|
||||
if(whichland == laRlyeh)
|
||||
if(specialland == laRlyeh)
|
||||
next = c2->land == laTemple && (cp2->land == laRlyeh || celldistAlt(c2) < celldistAlt(cp2) - 8);
|
||||
else
|
||||
next = celldistance(c2, cp2) == 8;
|
||||
@ -1038,14 +1053,13 @@ namespace peace {
|
||||
path[i]->item = itDodeca, items[itDodeca]--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void showMenu() {
|
||||
listLevels();
|
||||
dialog::init(XLAT(otherpuzzles ? "puzzles and exploration" : "memory game"), 0x40A040, 150, 100);
|
||||
|
||||
levellist = otherpuzzles ? explorelevels : simonlevels;
|
||||
|
||||
for(qty = 0; levellist[qty]; qty++)
|
||||
dialog::addItem(XLAT1(linf[levellist[qty]].name), 'a'+qty);
|
||||
for(int i = 0; i<qty; i++)
|
||||
dialog::addItem(XLAT1(linf[levellist[i]].name), 'a'+i);
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addItem(XLAT(otherpuzzles ? "memory game" : "puzzles and exploration"), '1');
|
||||
@ -1060,7 +1074,7 @@ namespace peace {
|
||||
|
||||
if(uni == '1') otherpuzzles = !otherpuzzles;
|
||||
else if(uni >= 'a' && uni < 'a' + qty) {
|
||||
whichland = levellist[uni - 'a'];
|
||||
specialland = levellist[uni - 'a'];
|
||||
restartGame(peace::on ? 0 : 'P');
|
||||
}
|
||||
else if(uni == '2') { hint = !hint; popScreen(); }
|
||||
|
Loading…
Reference in New Issue
Block a user