1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-29 19:40:35 +00:00

Merge branch 'zenorogue:master' into main

This commit is contained in:
Charlotte Peppers 2022-03-07 17:44:10 -07:00 committed by GitHub
commit 6663a33df4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 211 additions and 59 deletions

View File

@ -48,8 +48,12 @@ You can aim for the Orb of Yendor, or you can simply aim for as high score as po
## Modifications
OK, now lots of the above can be changed. You can change the geometry and topology (to Euclidean, spherical, or even to nonisotropic 3D geometries). You can play challenges based on
various in-game quests, and even try some other game genres in non-Euclidean spaces (roguelite aka shmup, racing, peaceful puzzles). Or use the engine for non-Euclidean computations
and visualizations (see [RogueViz](http://roguetemple.com/z/hyper/rogueviz.php)). Have fun!
various in-game quests, and even try some other game genres in non-Euclidean spaces (roguelite aka shmup, racing, peaceful puzzles).
## RogueViz
HyperRogue uses [RogueViz](http://roguetemple.com/z/hyper/rogueviz.php), which is our engine for non-Euclidean games, computations and visualizations. This repo includes the source code of RogueViz demos in subdirectory `rogueviz`, but
not the data, which is available on [itch.io](https://zenorogue.itch.io/rogueviz). RogueViz is funded by the National Science Centre, Poland, grant UMO-2019/35/B/ST6/04456.
## Development ##
@ -74,6 +78,7 @@ make
The `mymake` program builds HyperRogue in parts. It takes longer than the method shown above, but it uses significantly less memory during compilation, and when you change something, `mymake` will only recompile the changed file.
Additionally, it can be easily configured, e.g., to produce an optimized build, or to include addons (see `mymake.cpp` for some example invocations, and `devmods` for some example addons).
Most useful parameters include `-O3` (optimized build), `-rv` (include the RogueViz demos), `-vr` (build the VR version).
```
make mymake && ./mymake

View File

@ -4575,3 +4575,21 @@ Geometry:
- Goldberg-Coxeter improvements (larger limits supported, warn if outside of the supported limits, some are fixed)
- fixed fat edges in some H3 honeycombs
- fixed some bugs with Multi-dimensional Crystal quotient space
2022-03-01 09:39 Update 12.0l:
Orb-related fixes:
- Curse of Repulsion now correctly marked when used
- when having Orb of Freedom + Orb of Time, other orbs are no longer drained by Freedom checks
- Valentine's Easter Egg: Add +1 extra charge to Orb of Love
Geometry:
- fixed VR in product geometries
- portals between geometries: fixed some formulas, walking mode
- fixed dark lines in binary tiling x R raycasting which happened when we got a=0 in quadratic equation
- made Yendor/Haunted sight radius consistent when the tiling is changed
- infinite generation for single-land Camelot now only happens in hyperbolic geometry (also fixes the missing Grail in Crystal)
- additions and fixes to RogueViz
Other:
- fixed Crossroads wiki links
- fixed some settings incorrectly showing a warning on editing (this also brings back the 'play music when out of focus' option)

View File

@ -3075,7 +3075,7 @@ EX void addaura(shiftpoint h, color_t col, int fd) {
if(!haveaura_cached) return;
apply_joukowsky_aura(h);
int r = int(2*AURA + atan2(h[1], h[0]) * AURA / 2 / M_PI) % AURA;
int r = gmod(atan2(h[1], h[0]) * AURA / 2 / M_PI, AURA);
aurac[r][3] += auramemo << fd;
col = darkened(col);
aurac[r][0] += (col>>16)&255;

View File

@ -232,7 +232,7 @@ EX void buildCredits() {
"Kojiguchi Kazuki, baconcow, Alan, SurelyYouJest, hotdogPi, DivisionByZero, xXxWeedGokuxXx, jpystynen, Dmitry Marakasov, Alexandre Moine, Arthur O'Dwyer, "
"Triple_Agent_AAA, bluetailedgnat, Allalinor, Shitford, KittyTac, Christopher King, KosGD, TravelDemon, Bubbles, rdococ, frozenlake, MagmaMcFry, "
"Snakebird Priestess, roaringdragon2, Stopping Dog, bengineer8, Sir Light IJIJ, ShadeBlade, Saplou, shnourok, Ralith, madasa, 6% remaining, Chimera245, Remik Pi, alien foxcat thing, "
"Piotr Grochowski, Ann, still-flow, tyzone, Paradoxica, LottieRatWorld"
"Piotr Grochowski, Ann, still-flow, tyzone, Paradoxica, LottieRatWorld, aismallard"
);
#ifdef EXTRALICENSE
help += EXTRALICENSE;

View File

@ -13,8 +13,8 @@
#define _HYPER_H_
// version numbers
#define VER "12.0k"
#define VERNUM_HEX 0xA90B
#define VER "12.0l"
#define VERNUM_HEX 0xA90C
#include "sysconfig.h"

View File

@ -42,6 +42,7 @@ EX bool doPickupItemsWithMagnetism(cell *c) {
c4->item = c3->item;
moveEffect(movei(c3, c4, (cw+j).spin), moDeadBird);
c3->item = itNone;
markOrb(itCurseRepulsion);
}
}
}

View File

@ -11,15 +11,43 @@ embedding_type etype = eNatural;
map<cell*, kohvec> landscape_at;
map<cellwalker, kohvec> delta_at;
map<cellwalker, int> delta_id;
int qdelta;
void init_landscape(int dimensions) {
etype = eLandscape;
landscape_at.clear();
delta_at.clear();
delta_id.clear();
qdelta = 0;
landscape_at[currentmap->gamestart()].resize(dimensions, 0);
println(hlog, "initialized for ", currentmap->gamestart());
}
kohvec& get_landscape_at(cell *h);
void init_landscape_det(const vector<cell*>& ac) {
etype = eLandscape;
landscape_at.clear();
delta_at.clear();
delta_id.clear();
qdelta = 0;
landscape_at[currentmap->gamestart()].resize(0, 0);
for(cell *c: ac) get_landscape_at(c);
int dimensions = isize(delta_at);
landscape_at.clear();
landscape_at[currentmap->gamestart()].resize(dimensions, 0);
println(hlog, "qdelta = ", qdelta, " size of delta_at = ", isize(delta_at));
for(auto& d: delta_at) {
d.second.resize(dimensions, 0);
// d.second[id++] = 1;
d.second[delta_id[d.first]] = 1;
}
println(hlog, "initialized for ", currentmap->gamestart(), ", dimensions = ", dimensions);
}
void normalize(cellwalker& cw) {
int d = celldist(cw.at);
back:
@ -55,17 +83,25 @@ void normalize(cellwalker& cw) {
}
}
ld hrandd() {
return ((hrngen() & HRANDMAX) + .5) / HRANDMAX;
}
ld gaussian_random() {
return (hrand(1000) + hrand(1000) - hrand(1000) - hrand(1000)) / 1000.;
ld u1 = hrandd();
ld u2 = hrandd();
return sqrt(-2*log(u1)) * cos(2*M_PI*u2);
}
void apply_delta(cellwalker cw, kohvec& v) {
normalize(cw);
auto& da = delta_at[cw];
if(da.empty()) {
if(!delta_id.count(cw)) {
delta_id[cw] = qdelta++;
da.resize(isize(v));
for(auto& x: da) x = gaussian_random();
for(int i=0; i<min(200, isize(da)); i++)
if(i < isize(da)) da[i] = gaussian_random();
}
for(int i=0; i<isize(v); i++) v[i] += da[i];
@ -183,7 +219,7 @@ void get_coordinates(kohvec& v, cell *c, cell *c0) {
for(int i=0; i<MDIM; i++)
v[i] = h[i];
}
else if(euclid && bounded && WDIM == 2 && T0[0][1] == 0 && T0[1][0] == 0 && T0[0][0] == T0[1][1]) {
else if(euclid && bounded && S3 == 3 && WDIM == 2 && T0[0][1] == 0 && T0[1][0] == 0 && T0[0][0] == T0[1][1]) {
columns = 6;
alloc(v);
int s = T0[0][0];
@ -191,11 +227,11 @@ void get_coordinates(kohvec& v, cell *c, cell *c0) {
hyperpoint h1 = spin(120*degree*i) * h;
ld x = h1[1];
ld alpha = 2 * M_PI * x / s / (sqrt(3) / 2);
println(hlog, kz(x), " -> ", kz(alpha));
// println(hlog, kz(x), " -> ", kz(alpha));
v[2*i] = cos(alpha);
v[2*i+1] = sin(alpha);
}
println(hlog, kz(h), " -> ", v);
// println(hlog, kz(h), " -> ", v);
}
else if(euclid && bounded && WDIM == 2) {
columns = 4;

View File

@ -452,7 +452,8 @@ auto fifteen_hook =
if(fifteen_slides.empty()) {
fifteen_slides.emplace_back(
slide{"Introduction", 999, LEGAL::NONE,
"This is a collection of some geometric and topological variants of the Fifteen puzzle."
"This is a collection of some geometric and topological variants of the Fifteen puzzle. Most of these "
"are digital implementations of the mechanical designs by Henry Segerman."
,
[] (presmode mode) {}
});
@ -490,11 +491,16 @@ auto fifteen_hook =
add("coiled", "coiled", "Coiled fifteen puzzle by Henry Segerman.", "https://www.youtube.com/watch?v=rfAEgxNEOrQ");
add("Möbius band", "mobiusband", "Fifteen puzzle on a Möbius band.");
add("Kite-and-dart", "kitedart", "Kite-and-dart puzzle.");
add("29", "29", "The 29 puzzle by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
add("12", "12", "The 12 puzzle mentioned in the same video by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
add("124", "124", "The 124 puzzle mentioned in the same video by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
add("60", "60", "The 124 puzzle mentioned in the same video by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
add("Continental drift", "sphere19", "Based on the Continental Drift puzzle by Henry Segerman.", "https://www.youtube.com/watch?v=0uQx33KFMO0");
add_end(fifteen_slides);
}
cb(XLAT("variants of the fifteen puzzle"), &fifteen_slides[0], 'h');
cb(XLAT("variants of the fifteen puzzle"), &fifteen_slides[0], 'f');
});
#endif

View File

@ -440,6 +440,10 @@ auto msc = arg::add3("-analogs", enable)
slide_url(mode, 'm', "HyperRogue page about projections", "http://www.roguetemple.com/z/hyper/models.php");
setCanvas(mode, '0');
if(mode == pmStart) {
slide_backup(mapeditor::drawplayer);
slide_backup(vid.use_smart_range);
slide_backup(vid.smart_range_detail);
slide_backup(vid.linequality);
enable();
start_game();
slide_backup(cycle_models);

View File

@ -496,6 +496,7 @@ auto hooks =
mapstream::loadMap(s);
slide_backup(ray::fixed_map, true);
slide_backup(ray::max_iter_intra, y);
slide_backup(mapeditor::drawplayer, false);
};
};
@ -509,6 +510,7 @@ auto hooks =
if(twitter != "")
slide_url(mode, 't', "Twitter link", twitter);
slide_action(mode, 'r', "run this visualization", loader);
slidecommand = "portal options";
if(mode == tour::pmKey) pushScreen(intra::show_portals);
}
});

View File

@ -264,10 +264,7 @@ bool triangulate(kohvec d, neuron& w, map<cell*, neuron*>& find, transmatrix& re
}
if(diff < bdiff) bdiff = diff, candidate = w2, cdir = i;
}
if(cdir == -1) {
println(hlog, "not enough directions");
return false;
}
if(cdir == -1) break;
dirs.push_back(cdir);
other.push_back(candidate);
kv.push_back(candidate->net);
@ -291,6 +288,7 @@ bool triangulate(kohvec d, neuron& w, map<cell*, neuron*>& find, transmatrix& re
for(int i=0; i<q; i++) {
R[i][i] = vdot(kv[i], kv[i]);
if(R[i][i] < 1e-12) {
/*
auto head = [] (const vector<ld>& v) { vector<ld> res; for(int i=0; i<10; i++) res.push_back(v[i]); return res; };
println(hlog, "dot too small, i=", i,", dirs=", dirs);
println(hlog, "a = ", head(a));
@ -299,6 +297,7 @@ bool triangulate(kohvec d, neuron& w, map<cell*, neuron*>& find, transmatrix& re
println(hlog, "orig kv: ", head(z->net), " @ ", z->where);
for(auto z: kv)
println(hlog, "curr kv: ", head(z));
*/
return false;
}
for(int j=i+1; j<q; j++) {
@ -445,7 +444,7 @@ struct cellcrawler {
store(cw, i, j, cl);
}
}
if(gaussian) for(cellcrawlerdata& s: data)
if(gaussian || true) for(cellcrawlerdata& s: data)
s.dist = mydistance(s.orig.at, start.at);
}
@ -462,11 +461,13 @@ struct cellcrawler {
}
}
vector<vector<ld>> dispersion;
vector<vector<float>> dispersion;
};
double dispersion_end_at = 1.6;
bool dispersion_long;
double dispersion_precision = .0001;
int dispersion_each = 1;
@ -476,10 +477,10 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
cr.build(cellwalker(c,dir));
if(!gaussian) {
vector<ld> curtemp;
vector<ld> newtemp;
vector<float> curtemp;
vector<float> newtemp;
vector<int> qty;
vector<pair<ld*, ld*> > pairs;
vector<pair<float*, float*> > pairs;
int N = isize(net);
curtemp.resize(N, 0);
@ -503,8 +504,8 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
auto &d = cr.dispersion;
d.clear();
DEBBI(DF_LOG, ("Building dispersion, precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n"));
// DEBBI(DF_LOG, ("Building dispersion, precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n"));
for(iter=0; dispersion_count ? true : vmax > vmin * dispersion_end_at; iter++) {
if(iter % dispersion_each == 0) {
@ -527,10 +528,13 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
for(int i=0; i<N; i++)
if(curtemp[i] < vmin) vmin = curtemp[i];
else if(curtemp[i] > vmax) vmax = curtemp[i];
// if(iter % 50 == 0) println(hlog, "iter=", iter, " vmin=", vmin, " vmax=", vmax, " pairs=", isize(pairs));
}
dispersion_count = isize(d);
DEBB(DF_LOG, ("Dispersion count = ", dispersion_count));
if(!dispersion_count) {
if(!dispersion_long) dispersion_count = isize(d);
DEBB(DF_LOG, ("Dispersion count = ", isize(d), " celldist = ", celldist(c)));
}
/*
println(hlog, "dlast = ", d.back());
println(hlog, "dlast2 = ", d[d.size()-2]);
@ -542,7 +546,9 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
map<int, cellcrawler> scc;
pair<int, int> get_cellcrawler_id(cell *c) {
if(among(geometry, gZebraQuotient, gMinimal, gArnoldCat, gField435, gField534) || (euclid && quotient && !bounded) || IRREGULAR || (GDIM == 3 && sphere) || (hyperbolic && GDIM == 3 && quotient)
if(!bounded)
return make_pair(neuronId(*getNeuronSlow(c)), 0);
if(among(geometry, gZebraQuotient, gMinimal, gArnoldCat, gField435, gField534) || (euclid && quotient && !bounded) || IRREGULAR || (GDIM == 3 && sphere) || (hyperbolic && GDIM == 3)
|| (euclid && nonorientable)) {
// Zebra Quotient does exhibit some symmetries,
// but these are so small anyway that it is safer to just build
@ -644,20 +650,20 @@ void step() {
tt = pow(tt, ttpower);
double sigma = maxdist * tt;
int dispid = int(dispersion_count * tt);
if(qpct) {
int pct = (int) ((qpct * (t+.0)) / tmax);
if(pct != lpct) {
lpct = pct;
analyze();
}
if(gaussian)
println(hlog, format("t = %6d/%6d %3d%% sigma=%10.7lf maxudist=%10.7lf\n", t, tmax, pct, sigma, maxudist));
else
println(hlog, format("t = %6d/%6d %3d%% dispid=%5d maxudist=%10.7lf\n", t, tmax, pct, dispid, maxudist));
}
}
// if(gaussian)
// println(hlog, format("t = %6d/%6d %3d%% sigma=%10.7lf maxudist=%10.7lf\n", t, tmax, pct, sigma, maxudist));
// else
// println(hlog, format("t = %6d/%6d %3d%% dispid=%5d maxudist=%10.7lf\n", t, tmax, pct, dispid, maxudist));
// }
} //
int id = hrand(samples);
neuron& n = winner(id);
whowon.resize(samples);
@ -678,12 +684,18 @@ void step() {
cellcrawler& s = scc[cid.first];
s.sprawl(cellwalker(n.where, cid.second));
vector<double> fake(1,1);
vector<float> fake(0,0);
/* for(auto& sd: s.data)
fake.push_back(exp(-sqr(sd.dist/sigma))); */
int dispersion_count = isize(s.dispersion);
int dispid = int(dispersion_count * tt);
auto it = gaussian ? fake.begin() : s.dispersion[dispid].begin();
for(auto& sd: s.data) {
neuron *n2 = getNeuron(sd.target.at);
if(!n2) continue;
if(!n2) { it++; continue; }
n2->debug++;
double nu = learning_factor;
@ -697,15 +709,15 @@ void step() {
for(int k=0; k<columns; k++) {
n2->net[k] += nu * (data[id].val[k] - n2->net[k]);
if(isnan(n2->net[k]))
throw hr_exception("obtained nan somehow, nu = " + lalign(0, nu));
/* if(isnan(n2->net[k]))
throw hr_exception("obtained nan somehow, nu = " + lalign(0, nu)); */
}
}
for(auto& n2: net) {
/* for(auto& n2: net) {
if(n2.debug > 1) throw hr_exception("sprawler error");
n2.debug = 0;
}
} */
t--;
if(t == 0) analyze();
@ -893,7 +905,7 @@ void initialize_dispersion() {
DEBBI(DF_LOG, ("Initializing dispersion"));
if(gaussian) {
if(gaussian || true) {
DEBB(DF_LOG, ("dist = ", fts(mydistance(net[0].where, net[1].where))));
cell *c1 = net[cells/2].where;
vector<double> mapdist;
@ -902,19 +914,26 @@ void initialize_dispersion() {
maxdist = mapdist[isize(mapdist)*5/6] * distmul;
DEBB(DF_LOG, ("maxdist = ", fts(maxdist)));
}
dispersion_count = 0;
if(!gaussian)
DEBB(DF_LOG, ("dispersion precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n"));
DEBB(DF_LOG, ("building crawlers...\n"));
scc.clear();
for(int i=0; i<cells; i++) {
cell *c = net[i].where;
auto cid = get_cellcrawler_id(c);
if(!scc.count(cid.first)) {
DEBB(DF_LOG, ("Building cellcrawler id = ", itsh(cid.first)));
// DEBB(DF_LOG, ("Building cellcrawler id = ", itsh(cid.first)));
buildcellcrawler(c, scc[cid.first], cid.second);
}
}
DEBB(DF_LOG, ("crawlers constructed = ", isize(scc), "\n"));
lpct = -46130;
state |= KS_DISPERSION;
}
@ -1552,7 +1571,7 @@ int readArgs() {
gaussian = 0;
state &=~ KS_DISPERSION;
}
else if(argis("-somcgauss")) {
else if(argis("-somcgauss") || argis("-cgauss")) {
gaussian = 1;
state &=~ KS_DISPERSION;
}
@ -1582,11 +1601,18 @@ int readArgs() {
shift(); t = (t*1./tmax) * argi();
tmax = argi();
}
else if(argis("-somlong")) {
shift(); dispersion_long = argi();
}
else if(argis("-somlearn")) {
// this one can be changed at any moment
shift_arg_formula(learning_factor);
}
else if(argis("-som-analyze")) {
analyze();
}
else if(argis("-somrun")) {
initialize_rv();
set_neuron_initial();

View File

@ -1451,7 +1451,9 @@ void portal_slideshow(tour::ss::slideshow_callback cb) {
slide_backup(ray::exp_decay_poly, 30);
slide_backup(ray::fixed_map, true);
slide_backup(ray::max_iter_iso, 80);
#if CAP_VR
slide_backup(vid.cells_drawn_limit, 100);
slide_backup(mapeditor::drawplayer, false);
#if CAP_VR
slide_backup(vrhr::hsm);
slide_backup(vrhr::eyes);
slide_backup(vrhr::cscr);
@ -1472,6 +1474,7 @@ void portal_slideshow(tour::ss::slideshow_callback cb) {
loop = 2;
});
slidecommand = "notknot options";
if(mode == tour::pmKey) pushScreen(show);
}});
};

View File

@ -81,7 +81,8 @@ void model::load_obj(model_data& md) {
emit_material();
nextcol = 0xFFFFFFFF;
texname = "";
mtlname = scanline(fsm);
fsm.get<char>();
scan(fsm, mtlname);
}
if(s == "map_Kd") {
scan(fsm, texname);
@ -93,8 +94,12 @@ void model::load_obj(model_data& md) {
next_object:
object *co = nullptr;
bool textured = false;
fs.get<char>();
string oname = scanline(fs);
println(hlog, "reading object: ", oname);
md.objindex.push_back(isize(md.objs));
hyperpoint ctr = Hypc;
int cqty = 0;
while(true) {
if(feof(fs.f)) {
if(co) cgi.finishshape();
@ -117,6 +122,7 @@ void model::load_obj(model_data& md) {
h[1] /= 100;
h[2] /= 100;
vertices.push_back(h);
ctr += h; cqty++;
}
else if(s == "vt") {
ld u, v;
@ -134,7 +140,10 @@ void model::load_obj(model_data& md) {
else if(s == "usemtl") {
if(co) cgi.finishshape();
if(co) println(hlog, "vertices = ", co->sh.e-co->sh.s, " tvertices = ", isize(co->tv.tvertices));
string mtlname = scanline(fs);
fs.get<char>();
string mtlname;
scan(fs, mtlname);
//string mtlname = scanline(fs);
co = nullptr;
if(mtlname.find("Layer_Layer0") != string::npos) continue;
objects.push_back(make_shared<object>());
@ -196,6 +205,14 @@ void model::load_obj(model_data& md) {
tot.push_back(textured ? tvertices[vis[i].t] : point3(0,0,0));
}
if(!co) continue;
if(shift_to_ctr) {
hyperpoint ctr1 = ctr / cqty;
ctr1[3] = 0;
println(hlog, "ctr1 = ", ctr1, "hys = ", hys[0]);
for(auto& h: hys)
h -= ctr1;
}
hyperpoint norm = (hys[1] - hys[0]) ^ (hys[2] - hys[0]);
norm /= hypot_d(3, norm);
@ -255,7 +272,8 @@ void model::load_obj(model_data& md) {
println(hlog, "reading finished");
cgi.extra_vertices();
md.objindex.push_back(isize(md.objs));
cgi.extra_vertices();
}
model_data& model::get() {
@ -277,8 +295,8 @@ model_data& model::get() {
}
void model_data::render(const shiftmatrix& V) {
for(auto& obj: objs) {
queuepoly(V, obj->sh, obj->color);
for(auto& obj: objs) if(obj->color) {
queuepoly(V, obj->sh, obj->color);
}
}
@ -303,6 +321,7 @@ auto cf = addHook(hooks_configfile, 100, [] {
->editable(1, 100, 1, "3D model precision", "higher-precision models take more time to load and to render.", 'p')
->set_sets([] { dialog::numberdark = dialog::DONT_SHOW; })
;
param_b(shift_to_ctr, "shift_to_ctr");
});
}

View File

@ -435,6 +435,7 @@ void choose_projection() {
cmode = sm::SIDE | sm::MAYDARK;
gamescreen(0);
dialog::init(XLAT("choose projection"), 0xFFFFFFFF, 150, 0);
dynamicval<int> di(index);
for(int i=0; i<8; i++) {
index = i;
dynamicval<eModel> md(pmodel, pmodel);
@ -520,7 +521,7 @@ auto msc =
"We can also project a sphere to a sphere of different curvature. For example, what about the azimuthal equidistant projection from Earth to Moon? "
"This projection correctly maps the angles and distances from a chosen point at Earth. "
"Press 'o' to use the place on Earth you are in as the chosen point, try other projections, or change the other settings!"
"Press '5' to use the place on Earth you are in as the chosen point, try other projections, or change the other settings!"
,
[] (presmode mode) {
slide_url(mode, 't', "Twitter link (with description)", "https://twitter.com/ZenoRogue/status/1339946298460483589");
@ -533,9 +534,12 @@ auto msc =
slide_backup(pmodel, mdDisk);
slide_backup(pconf.scale, 1000);
slide_backup(pconf.alpha, 1000);
slide_backup(mapeditor::drawplayer, false);
start_game();
slide_backup(max_alpha, 192);
}
slidecommand = "options";
if(mode == tour::pmKey) pushScreen(show);
}});
});

View File

@ -169,7 +169,13 @@ void geodesic_screen(presmode mode, int id) {
use_angledir(mode, id == 0);
setCanvas(mode, '0');
if(mode == pmStart) stop_game(), pmodel = mdHorocyclic, geometry = gCubeTiling, pconf.clip_min = -10000, pconf.clip_max = +100, start_game();
if(mode == pmStart) {
slide_backup(pmodel);
slide_backup(pconf.clip_min);
slide_backup(pconf.clip_max);
slide_backup(vid.cells_drawn_limit);
stop_game(), pmodel = mdHorocyclic, geometry = gCubeTiling, pconf.clip_min = -10000, pconf.clip_max = +100, start_game();
}
add_stat(mode, [id] {
cmode |= sm::SIDE;
@ -540,6 +546,7 @@ slide dmv_slides[] = {
[] (presmode mode) {
setCanvas(mode, '0');
if(mode == pmStart) {
tour::slide_backup(mapeditor::drawplayer, false);
enable_earth();
View = Id;
@ -653,6 +660,7 @@ slide dmv_slides[] = {
set_geometry(gFieldQuotient);
*/
start_game();
tour::slide_backup(mapeditor::drawplayer, false);
pentaroll::create_pentaroll(true);
tour::slide_backup(anims::period, 30000.);
tour::slide_backup(sightranges[geometry], 4);
@ -1132,7 +1140,7 @@ slide dmv_slides[] = {
int phooks =
0 +
addHook_slideshows(100, [] (tour::ss::slideshow_callback cb) {
cb(XLAT("Playing with Impossibility"), &dmv_slides[0], 'p');
cb(XLAT("Playing with Impossibility"), &dmv_slides[0], 'i');
});
}

View File

@ -235,6 +235,7 @@ void choose_presentation() {
if(!tour::texts) nomenukey = true;
popScreenAll();
tour::start();
if(!tour::on) tour::start();
});
});
@ -250,7 +251,7 @@ int phooks =
+ addHook(dialog::hooks_display_dialog, 100, [] () {
if(current_screen_cfunction() == showStartMenu) {
dialog::addBreak(100);
dialog::addBigItem(XLAT("RogueViz demos"), 'p');
dialog::addBigItem(XLAT("RogueViz demos"), 'd');
dialog::add_action([] () { pushScreen(choose_presentation); });
}
});

View File

@ -40,11 +40,15 @@ bool snow_glitch = false;
/* disable textures */
bool snow_texture = true;
/* draw single objects? */
bool single_objects = true;
int snow_shape = 0;
struct snowball {
transmatrix T;
int model_id;
int object_id;
};
map<cell*, vector<snowball>> snowballs_at;
@ -134,14 +138,29 @@ bool draw_snow(cell *c, const shiftmatrix& V) {
}
}
for(int t=0; t<cnt; t++)
v.emplace_back(snowball{random_snow_matrix(c), isize(models) ? hrand(isize(models)) : 0});
for(int t=0; t<cnt; t++) {
snowball b{random_snow_matrix(c), 0, -1};
if(isize(models)) {
b.model_id = hrand(isize(models));
if(single_objects)
b.object_id = hrand(isize(models[b.model_id].get().objindex)-1);
}
v.emplace_back(b);
}
}
poly_outline = 0xFF;
for(auto& T: snowballs_at[c]) {
if(models.size()) {
models[T.model_id].render(V*T.T);
if(T.object_id == -1)
models[T.model_id].render(V*T.T);
else {
auto& m = models[T.model_id].get();
for(int i=m.objindex[T.object_id]; i<m.objindex[T.object_id+1]; i++) {
auto& obj = m.objs[i];
if(obj->color) queuepoly(V*T.T, obj->sh, obj->color);
}
}
}
else {
auto& p = queuepoly(V * T.T, shapeid(snow_shape), snow_color);