mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-12-14 18:18:05 +00:00
10.0g
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user