From d2166aef08c557a82aadf71add2321763b07ce56 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Thu, 14 Nov 2024 18:21:49 +0100 Subject: [PATCH] show map type, improved expansion --- config.cpp | 16 ++++++++++++++++ control.cpp | 4 ++-- expansion.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++-------- geom-exp.cpp | 2 +- locations.cpp | 13 +++++++++---- rulegen.cpp | 31 ++++++++++++++++++++++++++++--- 6 files changed, 98 insertions(+), 18 deletions(-) diff --git a/config.cpp b/config.cpp index 593840a9..addb7f39 100644 --- a/config.cpp +++ b/config.cpp @@ -3507,6 +3507,22 @@ EX int config3 = addHook(hooks_configfile, 100, [] { -> editable("apply color/pattern changes to canvas automatically", 'l'); param_str(ccolor::color_formula, "color_formula") -> editor = [] { ccolor::config_formula(false); }; + + param_i(count_max_cells, "count_max_cells", 100000)->editable(100, 1000000, log(10), "max cells to count", + "Counting stops if that many cells are reached.", 'c') + ->set_sets([] { dialog::scaleLog(); }); + + param_i(count_max_dist, "count_max_dist", 999)->editable(5, 1000, 1, "max distance to check", + "Counting stops if this distance is reached.", 'd'); + + param_b(use_analyzer, "count_use_analyzer", true)->editable("use analyzer if possible", 'a'); + param_b(use_sight_range_instead, "count_use_sight", true)->editable("use sight range instead", 's'); + +/* 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(); */ + }); EX void switchcolor(unsigned int& c, unsigned int* cs) { diff --git a/control.cpp b/control.cpp index e07e2c01..c125d3e0 100644 --- a/control.cpp +++ b/control.cpp @@ -555,13 +555,13 @@ EX array keys_numpad = {{SDLK_KP6, SDLK_KP3, SDLK_KP2, SDLK_KP1, SDLK_KP EX void handleKeyNormal(int sym, int uni) { - if(cheater && sym < 256 && sym > 0) { + if(cheater && sym < 256 && sym > 0 && !dialog::key_actions.count(uni)) { if(applyCheat(uni)) uni = sym = 0; } #if CAP_SHOT - if(uni == 'A') { pushScreen(shot::menu); uni = sym = 0; } + if(uni == 'A' && !dialog::key_actions.count('A')) { pushScreen(shot::menu); uni = sym = 0; } #endif if(DEFAULTNOR(sym)) handlePanning(sym, uni); diff --git a/expansion.cpp b/expansion.cpp index 7f52a5d9..eb0f8ddb 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -732,6 +732,19 @@ string produce_coef_formula(vector coef) { } EX bool auto_extend = true; +EX bool use_sight_range_instead = true; + +EX int count_max_cells = 100000; +EX int count_max_dist = 999; + +void configure_counter() { + dialog::init(""); + add_edit(use_analyzer); + add_edit(count_max_dist); + add_edit(count_max_cells); + add_edit(use_sight_range_instead); + dialog::display(); + } void expansion_analyzer::view_distances_dialog() { static int lastticks; @@ -749,8 +762,16 @@ void expansion_analyzer::view_distances_dialog() { auto& expansion = get_expansion(); bool really_use_analyzer = use_analyzer && sizes_known(); + bool nomore = false; + bool knowall = false; if(really_use_analyzer) { + dialog::addSelItem(XLAT("based on analysis"), + reg3::exact_rules() ? XLAT("3D rules") : + currentmap->strict_tree_rules() ? XLAT("generated rules") : + XLAT("built-in rules"), 'A' + ); + dialog::add_action_push(configure_counter); int t; if(reg3::exact_rules() || currentmap->strict_tree_rules()) { if(!N) preliminary_grouping(); @@ -762,33 +783,47 @@ void expansion_analyzer::view_distances_dialog() { qty[r] = expansion.get_descendants(r, t); } else { + int count_range = (GDIM == 2 && use_sight_range_instead) ? get_sightrange() : count_max_dist; + count_range = min(count_range, count_max_dist); + count_range = min(count_range, maxlen-1); + + celllister cl(cwt.at, count_range, count_max_cells, NULL); + if(cl.reason == celllister::srAll) knowall = true; + if(cl.reason == celllister::srCount) count_range = cl.dists.back(); + if(distance_from == dfPlayer) { - celllister cl(cwt.at, closed_manifold ? maxlen-1 : gamerange(), 100000, NULL); for(int d: cl.dists) if(d >= 0 && d < maxlen) qty[d]++; } else { - celllister cl(cwt.at, closed_manifold ? maxlen-1 : gamerange(), 100000, NULL); for(cell *c: cl.lst) if((not_only_descendants || is_descendant(c)) && curr_dist(c) < maxlen) qty[curr_dist(c)]++; } + dialog::addSelItem(XLAT("cell counting range"), its(count_range), 'A'); + dialog::add_action_push(configure_counter); #if !CAP_GMP - if(sizes_known() && !not_only_descendants) { + if((sizes_known() || bt::in()) && !not_only_descendants && !knowall) { find_coefficients(); - if(gamerange()+1 >= valid_from && coefficients_known == 2) { - for(int i=gamerange()+1; i= valid_from && coefficients_known == 2) { + for(int i=count_range+1; ilistindex = tmps[i]; } }; - + /** \brief automatically generate a list of nearby cells */ struct celllister : manual_celllister { vector dists; - + + enum stop_reason { srAll, srCount, srCell, srDistance }; + stop_reason reason; + void add_at(cell *c, int d) { if(add(c)) dists.push_back(d); } @@ -439,13 +442,15 @@ struct celllister : manual_celllister { cell *c = lst[i]; if(maxdist) forCellCM(c2, c) { add_at(c2, dists[i]+1); - if(c2 == breakon) return; + if(c2 == breakon) { reason = srCell; return; } } if(c == last) { - if(isize(lst) >= maxcount || dists[i]+1 == maxdist) break; + if(isize(lst) >= maxcount) { reason = srCount; return; } + if(dists[i]+1 == maxdist) { reason = srDistance; return; } last = lst[isize(lst)-1]; } } + reason = srAll; } /** \brief for a given cell c on the list, return its distance from orig */ diff --git a/rulegen.cpp b/rulegen.cpp index cbd5fe80..a7a16a2c 100644 --- a/rulegen.cpp +++ b/rulegen.cpp @@ -2582,15 +2582,40 @@ EX void show() { "tessellations (contrary to the basic implementation of Archimedean, tes, and unrectified/warped/untruncated tessellations).\n\nYou can convert mostly any " "non-spherical periodic 2D tessellation to strict tree based.\n\nSwitching the map format erases your map.")); - if(aperiodic) { + if(closed_manifold) { + dialog::addInfo("not available (and not necessary) in closed manifolds"); + dialog::addBack(); + dialog::display(); + return; + } + else if(aperiodic) { dialog::addInfo("not available in aperiodic tessellations"); dialog::addBack(); dialog::display(); + return; } - else if(WDIM == 3) { - dialog::addInfo("not available in 3D tessellations"); + else if(bt::in()) { + dialog::addInfo("not available in binary-like tilings"); dialog::addBack(); dialog::display(); + return; + } + else if(WDIM == 3) { + if(reg3::in() && reg3::variation_rule_available()) + dialog::addInfo("precomputed rule used (for specific variation)"); + else if(reg3::in() && reg3::pure_rule_available()) + dialog::addInfo("precomputed rule used (for regular honeycomb)"); + else if(euc::in()) + dialog::addInfo("no rule needed for Euclidean"); + else if(reg3::in()) { + dialog::addInfo("not available in this regular honeycomb"); + dialog::addInfo("fallback implementation used"); + } + else + dialog::addInfo("not available in this 3D tessellation"); + dialog::addBack(); + dialog::display(); + return; } dialog::addBoolItem(XLAT("in tes internal format"), arb::in(), 't');