mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
smart display range
This commit is contained in:
parent
c40953fbad
commit
1ba1b141f3
89
config.cpp
89
config.cpp
@ -290,6 +290,10 @@ void initConfig() {
|
||||
addsaver(texture::texture_aura, "texture-aura", false);
|
||||
#endif
|
||||
|
||||
addsaver(vid.use_smart_range, "smart-range", 0);
|
||||
addsaver(vid.smart_range_detail, "smart-range-detail", 8);
|
||||
addsaver(vid.cells_drawn_limit, "limit on cells drawn", 10000);
|
||||
|
||||
#if CAP_SHMUP
|
||||
shmup::initConfig();
|
||||
#endif
|
||||
@ -555,6 +559,59 @@ void loadNewConfig(FILE *f) {
|
||||
}
|
||||
allconfigs.clear();
|
||||
}
|
||||
|
||||
void edit_sightrange() {
|
||||
if(vid.use_smart_range == 0) {
|
||||
dialog::editNumber(sightrange_bonus, -5, allowIncreasedSight() ? 3 : 0, 1, 0, XLAT("sight range"),
|
||||
XLAT("Roughly 42% cells are on the edge of your sight range. Reducing "
|
||||
"the sight range makes HyperRogue work faster, but also makes "
|
||||
"the game effectively harder."));
|
||||
dialog::reaction = [] () {
|
||||
doOvergenerate();
|
||||
};
|
||||
}
|
||||
else {
|
||||
dialog::editNumber(vid.smart_range_detail, 1, 50, 1, 8, XLAT("minimum visible cell in pixels"), "");
|
||||
}
|
||||
dialog::extra_options = [] () {
|
||||
dialog::addBoolItem(XLAT("draw range based on distance"), vid.use_smart_range == 0, 'd');
|
||||
dialog::add_action([] () { vid.use_smart_range = 0; popScreen(); edit_sightrange(); });
|
||||
if(allowIncreasedSight()) {
|
||||
dialog::addBoolItem(XLAT("draw based on size in the projection (no generation)"), vid.use_smart_range == 1, 'n');
|
||||
dialog::add_action([] () { vid.use_smart_range = 1; popScreen(); edit_sightrange(); });
|
||||
}
|
||||
if(allowChangeRange()) {
|
||||
dialog::addBoolItem(XLAT("draw based on size in the projection (generation)"), vid.use_smart_range == 2, 'g');
|
||||
dialog::add_action([] () { vid.use_smart_range = 2; popScreen(); edit_sightrange(); });
|
||||
}
|
||||
if(vid.use_smart_range == 0 && allowChangeRange()) {
|
||||
dialog::addSelItem(XLAT("generation range bonus"), its(genrange_bonus), 'o');
|
||||
dialog::add_action([] () { genrange_bonus = sightrange_bonus; doOvergenerate(); });
|
||||
dialog::addSelItem(XLAT("game range bonus"), its(gamerange_bonus), 'O');
|
||||
dialog::add_action([] () { gamerange_bonus = sightrange_bonus; doOvergenerate(); });
|
||||
}
|
||||
if(!allowChangeRange() || !allowIncreasedSight()) {
|
||||
dialog::addItem(XLAT("enable the cheat mode for additional options"), 'C');
|
||||
dialog::add_action(enable_cheat);
|
||||
}
|
||||
dialog::addSelItem(XLAT("cells drawn"), its(cells_drawn), 'c');
|
||||
dialog::add_action([] () {
|
||||
popScreen();
|
||||
dialog::editNumber(vid.cells_drawn_limit, 100, 1000000, log(10), 10000, XLAT("limit on cells drawn"),
|
||||
XLAT("This limit exists to protect the engine from freezing when too many cells would be drawn according to the current options.")
|
||||
);
|
||||
dialog::scaleLog();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
void menuitem_sightrange(char c = 'r') {
|
||||
if(vid.use_smart_range)
|
||||
dialog::addSelItem(XLAT("minimum visible cell in pixels"), fts(vid.smart_range_detail), c);
|
||||
else
|
||||
dialog::addSelItem(XLAT("sight range"), its(sightrange_bonus), c);
|
||||
dialog::add_action(edit_sightrange);
|
||||
}
|
||||
|
||||
void loadConfig() {
|
||||
|
||||
@ -663,8 +720,8 @@ void showGraphConfig() {
|
||||
|
||||
dialog::addSelItem(XLAT("font scale"), its(fontscale), 'b');
|
||||
|
||||
dialog::addSelItem(XLAT("sight range"), its(sightrange_bonus), 'r');
|
||||
|
||||
menuitem_sightrange();
|
||||
|
||||
dialog::addSelItem(XLAT("compass size"), its(vid.mobilecompasssize), 'c');
|
||||
|
||||
dialog::addSelItem(XLAT("aura brightness"), its(vid.aurastr), 'z');
|
||||
@ -701,26 +758,6 @@ void showGraphConfig() {
|
||||
XLAT("movement animation speed"),
|
||||
XLAT("+5 = move instantly"));
|
||||
|
||||
if(xuni == 'r') {
|
||||
dialog::editNumber(sightrange_bonus, -5, allowIncreasedSight() ? 3 : 0, 1, 0, XLAT("sight range"),
|
||||
XLAT("Roughly 42% cells are on the edge of your sight range. Reducing "
|
||||
"the sight range makes HyperRogue work faster, but also makes "
|
||||
"the game effectively harder."));
|
||||
dialog::reaction = [] () {
|
||||
doOvergenerate();
|
||||
};
|
||||
dialog::extra_options = [] () {
|
||||
if(allowChangeRange()) {
|
||||
dialog::addSelItem(XLAT("generation range bonus"), its(genrange_bonus), 'o');
|
||||
dialog::add_action([] () { genrange_bonus = sightrange_bonus; doOvergenerate(); });
|
||||
dialog::addSelItem(XLAT("game range bonus"), its(gamerange_bonus), 'O');
|
||||
dialog::add_action([] () { gamerange_bonus = sightrange_bonus; doOvergenerate(); });
|
||||
}
|
||||
if(!allowChangeRange() || !allowIncreasedSight())
|
||||
dialog::addInfo(XLAT("note: enable the cheat mode for additional options"));
|
||||
};
|
||||
}
|
||||
|
||||
if(xuni == 'k') {
|
||||
glyphsortorder = eGlyphsortorder((glyphsortorder+6+(shiftmul>0?1:-1)) % gsoMAX);
|
||||
}
|
||||
@ -1177,10 +1214,12 @@ void show3D() {
|
||||
using namespace geom3;
|
||||
dialog::init(XLAT("3D configuration"));
|
||||
|
||||
dialog::addSelItem(XLAT("High detail range"), fts(highdetail), 'n');
|
||||
dialog::addSelItem(XLAT("Mid detail range"), fts(middetail), 'm');
|
||||
if(vid.use_smart_range == 0) {
|
||||
dialog::addSelItem(XLAT("High detail range"), fts(highdetail), 'n');
|
||||
dialog::addSelItem(XLAT("Mid detail range"), fts(middetail), 'm');
|
||||
dialog::addBreak(50);
|
||||
}
|
||||
|
||||
dialog::addBreak(50);
|
||||
dialog::addSelItem(XLAT("Camera level above the plane"), fts3(camera), 'c');
|
||||
dialog::addSelItem(XLAT("Ground level below the plane"), fts3(depth), 'g');
|
||||
|
||||
|
@ -682,6 +682,8 @@ namespace conformal {
|
||||
}
|
||||
|
||||
dialog::addSelItem(XLAT("vertical stretch"), fts3(vid.stretch), 's');
|
||||
|
||||
menuitem_sightrange('R');
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addItem(XLAT("history mode"), 'a');
|
||||
|
10
graph.cpp
10
graph.cpp
@ -3353,7 +3353,7 @@ void pushdown(cell *c, int& q, const transmatrix &V, double down, bool rezoom, b
|
||||
|
||||
bool dodrawcell(cell *c) {
|
||||
// do not display out of range cells, unless on torus
|
||||
if(c->pathdist == PINFD && geometry != gTorus)
|
||||
if(c->pathdist == PINFD && geometry != gTorus && vid.use_smart_range == 0)
|
||||
return false;
|
||||
// do not display not fully generated cells, unless a cheater
|
||||
if(c->mpdist > 7 && !cheater && !autocheat) return false;
|
||||
@ -3535,6 +3535,8 @@ int colorhash(color_t i) {
|
||||
|
||||
void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
cells_drawn++;
|
||||
|
||||
#if CAP_TEXTURE
|
||||
if(texture::saving) {
|
||||
texture::config.apply(c, V, 0xFFFFFFFF);
|
||||
@ -3564,7 +3566,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
if(callhandlers(false, hooks_drawcell, c, V)) return;
|
||||
|
||||
ld dist0 = hdist0(tC0(V)) - 1e-6;
|
||||
if(dist0 < geom3::highdetail) detaillevel = 2;
|
||||
if(vid.use_smart_range) detaillevel = 2;
|
||||
else if(dist0 < geom3::highdetail) detaillevel = 2;
|
||||
else if(dist0 < geom3::middetail) detaillevel = 1;
|
||||
else detaillevel = 0;
|
||||
|
||||
@ -5245,6 +5248,7 @@ void drawthemap() {
|
||||
callhooks(hooks_drawmap);
|
||||
|
||||
frameid++;
|
||||
cells_drawn = 0;
|
||||
|
||||
wavephase = (-(ticks / 100)) & 7;
|
||||
|
||||
@ -5316,7 +5320,7 @@ void drawthemap() {
|
||||
else if(archimedean)
|
||||
arcm::draw();
|
||||
else
|
||||
drawrec(viewctr, hsOrigin, cview());
|
||||
drawrec(viewctr, hsOrigin, cview(), 0);
|
||||
drawWormSegments();
|
||||
drawBlizzards();
|
||||
drawArrowTraps();
|
||||
|
26
hyper.h
26
hyper.h
@ -1047,6 +1047,10 @@ struct videopar {
|
||||
bool skipstart; // skip the start menu
|
||||
int quickmouse; // quick mouse on the map
|
||||
int timeformat; // time format used in the message log
|
||||
|
||||
int use_smart_range; // 0 = distance-based, 1 = model-based, 2 = model-based and generate
|
||||
ld smart_range_detail;// minimum visible cell for modes 1 and 2
|
||||
int cells_drawn_limit;
|
||||
};
|
||||
|
||||
extern videopar vid;
|
||||
@ -3798,7 +3802,7 @@ void queuestr(const hyperpoint& h, int size, const string& chr, color_t col, int
|
||||
void queuechr(const transmatrix& V, double size, char chr, color_t col, int frame = 0);
|
||||
|
||||
extern bool just_gmatrix;
|
||||
void drawrec(const heptspin& hs, hstate s, const transmatrix& V);
|
||||
void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev = 0);
|
||||
|
||||
bool haveLeaderboard(int id);
|
||||
int get_currentscore(int id);
|
||||
@ -4272,5 +4276,25 @@ struct exp_parser {
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CAP_COMPLEX2
|
||||
namespace brownian {
|
||||
const int level = 5;
|
||||
void init(cell *c);
|
||||
void build(cell *c, int d);
|
||||
void explosion(cell *c, int x);
|
||||
};
|
||||
#else
|
||||
namespace brownian {
|
||||
inline void dissolve_brownian(cell*, int) {};
|
||||
inline void build(cell *c, int d) {}
|
||||
inline void init(cell *c) {}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ONEMPTY if(d == 7 && passable(c, NULL, 0) && !safety)
|
||||
|
||||
void enable_cheat();
|
||||
|
||||
extern int cells_drawn;
|
||||
}
|
||||
|
||||
|
77
hypgraph.cpp
77
hypgraph.cpp
@ -626,9 +626,34 @@ transmatrix applyspin(const heptspin& hs, const transmatrix& V) {
|
||||
return hs.spin ? V * spin(hs.spin*2*M_PI/S7) : V;
|
||||
}
|
||||
|
||||
bool in_smart_range(const transmatrix& T) {
|
||||
hyperpoint h1, h2, h3;
|
||||
applymodel(tC0(T), h1);
|
||||
ld x = vid.xcenter + vid.radius * h1[0];
|
||||
ld y = vid.ycenter + vid.radius * h1[1] * vid.stretch;
|
||||
if(x > vid.xres * 2) return false;
|
||||
if(x < -vid.xres) return false;
|
||||
if(y > vid.yres * 2) return false;
|
||||
if(y < -vid.yres) return false;
|
||||
ld epsilon = 0.01;
|
||||
applymodel(T * xpush0(epsilon), h2);
|
||||
ld x1 = vid.radius * abs(h2[0] - h1[0]) / epsilon;
|
||||
ld y1 = vid.radius * abs(h2[1] - h1[1]) * vid.stretch / epsilon;
|
||||
applymodel(T * ypush(epsilon) * C0, h3);
|
||||
ld x2 = vid.radius * abs(h3[0] - h1[0]) / epsilon;
|
||||
ld y2 = vid.radius * abs(h3[1] - h1[1]) * vid.stretch / epsilon;
|
||||
ld scale = sqrt(hypot(x1, y1) * hypot(x2, y2)) * scalefactor * hcrossf7;
|
||||
return
|
||||
scale > vid.smart_range_detail &&
|
||||
x - 2 * max(x1, x2) < vid.xres &&
|
||||
x + 2 * max(x1, x2) > 0 &&
|
||||
y - 2 * max(y1, y2) < vid.yres &&
|
||||
y + 2 * max(y1, y2) > 0;
|
||||
}
|
||||
|
||||
// in hyperbolic quotient geometries, relying on pathdist is not sufficient
|
||||
bool in_qrange(const transmatrix& V) {
|
||||
if(!quotient || !hyperbolic) return true;
|
||||
if(!quotient || !hyperbolic || vid.use_smart_range) return true;
|
||||
return V[2][2] < cosh(crossf * get_sightrange_ambush());
|
||||
}
|
||||
|
||||
@ -688,7 +713,7 @@ void drawrec(cell *c, const transmatrix& V) {
|
||||
}
|
||||
}
|
||||
|
||||
void drawrec(const heptspin& hs, hstate s, const transmatrix& V) {
|
||||
void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev) {
|
||||
|
||||
// calc_relative_matrix(cwt.c, hs.at);
|
||||
|
||||
@ -699,6 +724,14 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) {
|
||||
|
||||
bool draw = c->pathdist < PINFD;
|
||||
|
||||
if(cells_drawn > vid.cells_drawn_limit || reclev >= 100 || std::isinf(V[2][2]) || std::isnan(V[2][2]))
|
||||
draw = false;
|
||||
else if(vid.use_smart_range) {
|
||||
draw = reclev < 2 ? true : in_smart_range(V);
|
||||
if(draw && vid.use_smart_range == 2)
|
||||
setdist(c, 7, NULL);
|
||||
}
|
||||
|
||||
if(GOLDBERG) {
|
||||
gp::drawrec(c, actualV(hs, V1));
|
||||
}
|
||||
@ -734,7 +767,7 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) {
|
||||
hstate s2 = transition(s, d);
|
||||
if(s2 == hsError) continue;
|
||||
heptspin hs2 = hs + d + wstep;
|
||||
drawrec(hs2, s2, V * heptmove[d]);
|
||||
drawrec(hs2, s2, V * heptmove[d], reclev+1);
|
||||
}
|
||||
|
||||
}
|
||||
@ -838,19 +871,31 @@ void drawEuclidean() {
|
||||
// Mat[2][0] = x*x/10;
|
||||
// Mat[2][1] = y*y/10;
|
||||
// Mat = Mat * xpush(x-30) * ypush(y-30);
|
||||
|
||||
int cx, cy, shift;
|
||||
getcoord0(tC0(Mat), cx, cy, shift);
|
||||
if(cx >= 0 && cy >= 0 && cx < vid.xres && cy < vid.yres) {
|
||||
if(dx < mindx) mindx = dx;
|
||||
if(dy < mindy) mindy = dy;
|
||||
if(dx > maxdx) maxdx = dx;
|
||||
if(dy > maxdy) maxdy = dy;
|
||||
}
|
||||
if(cx >= -cellrad && cy >= -cellrad && cx < vid.xres+cellrad && cy < vid.yres+cellrad)
|
||||
if(dodrawcell(cw.at)) {
|
||||
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
|
||||
|
||||
if(vid.use_smart_range) {
|
||||
if(in_smart_range(Mat)) {
|
||||
if(dx < mindx) mindx = dx;
|
||||
if(dy < mindy) mindy = dy;
|
||||
if(dx > maxdx) maxdx = dx;
|
||||
if(dy > maxdy) maxdy = dy;
|
||||
if(dodrawcell(cw.at))
|
||||
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int cx, cy, shift;
|
||||
getcoord0(tC0(Mat), cx, cy, shift);
|
||||
if(cx >= 0 && cy >= 0 && cx < vid.xres && cy < vid.yres) {
|
||||
if(dx < mindx) mindx = dx;
|
||||
if(dy < mindy) mindy = dy;
|
||||
if(dx > maxdx) maxdx = dx;
|
||||
if(dy > maxdy) maxdy = dy;
|
||||
}
|
||||
if(cx >= -cellrad && cy >= -cellrad && cx < vid.xres+cellrad && cy < vid.yres+cellrad)
|
||||
if(dodrawcell(cw.at)) {
|
||||
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,6 +1042,8 @@ void panning(hyperpoint hf, hyperpoint ht) {
|
||||
playermoved = false;
|
||||
}
|
||||
|
||||
int cells_drawn;
|
||||
|
||||
void fullcenter() {
|
||||
if(playerfound && false) centerpc(INF);
|
||||
else {
|
||||
|
45
menus.cpp
45
menus.cpp
@ -406,6 +406,28 @@ void showDisplayMode() {
|
||||
};
|
||||
}
|
||||
|
||||
void enable_cheat() {
|
||||
if(tactic::on && gold()) {
|
||||
addMessage(XLAT("Not available in the pure tactics mode!"));
|
||||
}
|
||||
else if(daily::on) {
|
||||
addMessage(XLAT("Not available in the daily challenge!"));
|
||||
}
|
||||
else if(!cheater) {
|
||||
cheater++;
|
||||
addMessage(XLAT("You activate your demonic powers!"));
|
||||
#if ISMOBILE==0
|
||||
addMessage(XLAT("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc."));
|
||||
#endif
|
||||
popScreen();
|
||||
}
|
||||
else {
|
||||
popScreen();
|
||||
firstland = princess::challenge ? laPalace : laIce;
|
||||
restart_game();
|
||||
}
|
||||
}
|
||||
|
||||
// -- game modes --
|
||||
|
||||
void switchHardcore() {
|
||||
@ -484,27 +506,8 @@ void showChangeMode() {
|
||||
pushScreen(daily::showMenu);
|
||||
#endif
|
||||
|
||||
else if(uni == 'c') {
|
||||
if(tactic::on && gold()) {
|
||||
addMessage(XLAT("Not available in the pure tactics mode!"));
|
||||
}
|
||||
else if(daily::on) {
|
||||
addMessage(XLAT("Not available in the daily challenge!"));
|
||||
}
|
||||
else if(!cheater) {
|
||||
cheater++;
|
||||
addMessage(XLAT("You activate your demonic powers!"));
|
||||
#if ISMOBILE==0
|
||||
addMessage(XLAT("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc."));
|
||||
#endif
|
||||
popScreen();
|
||||
}
|
||||
else {
|
||||
popScreen();
|
||||
firstland = princess::challenge ? laPalace : laIce;
|
||||
restart_game();
|
||||
}
|
||||
}
|
||||
else if(uni == 'c')
|
||||
enable_cheat();
|
||||
|
||||
else if(xuni == 'e')
|
||||
runGeometryExperiments();
|
||||
|
@ -293,7 +293,11 @@ void initgame() {
|
||||
if(quotient || sphere)
|
||||
for(cell *c: currentmap->allcells()) setdist(c, 8, NULL);
|
||||
|
||||
if(!cheater) gamerange_bonus = genrange_bonus = 0;
|
||||
if(!cheater) {
|
||||
gamerange_bonus = genrange_bonus = 0;
|
||||
if(vid.use_smart_range == 2) vid.use_smart_range = 1;
|
||||
}
|
||||
if(!allowIncreasedSight()) vid.use_smart_range = 0;
|
||||
}
|
||||
|
||||
bool havesave = true;
|
||||
|
10
tour.cpp
10
tour.cpp
@ -588,11 +588,12 @@ slide default_slides[] = {
|
||||
"The next slide shows another model, called the Poincaré upper half-plane model. In this model, "
|
||||
"horocycles centered at one specific ideal point are drawn as straight lines.",
|
||||
[] (presmode mode) {
|
||||
static int smart;
|
||||
if(mode == 1)
|
||||
pmodel = mdHalfplane;
|
||||
pmodel = mdHalfplane, smart = vid.use_smart_range, vid.use_smart_range = 2;
|
||||
if(mode == 2)
|
||||
conformal::rotation = cwt.at->land == laDungeon ? 0 : 2;
|
||||
if(mode == 3) pmodel = mdDisk, conformal::rotation = 0;
|
||||
if(mode == 3) pmodel = mdDisk, conformal::rotation = 0, vid.use_smart_range = smart;
|
||||
}
|
||||
},
|
||||
{"Curvature", 29, LEGAL_ANY,
|
||||
@ -739,13 +740,16 @@ slide default_slides[] = {
|
||||
"If you want, press '5' to see it rendered as a spiral, although it takes lots of time and "
|
||||
"memory.",
|
||||
[] (presmode mode) {
|
||||
if(mode == 1) pmodel = mdBand, conformal::create(), conformal::rotation = 0;
|
||||
static int smart;
|
||||
if(mode == 1) pmodel = mdBand, conformal::create(), conformal::rotation = 0,
|
||||
smart = vid.use_smart_range, vid.use_smart_range = 2;
|
||||
if(mode == 3) {
|
||||
conformal::clear(), pmodel = mdDisk;
|
||||
resetview();
|
||||
drawthemap();
|
||||
centerpc(INF);
|
||||
conformal::includeHistory = false;
|
||||
vid.use_smart_range = smart;
|
||||
}
|
||||
#if CAP_SDL
|
||||
slidecommand = "render spiral";
|
||||
|
Loading…
Reference in New Issue
Block a user