rogueviz:: antidesitter updated

This commit is contained in:
Zeno Rogue 2022-06-23 09:31:39 +02:00
parent de4b436d48
commit e07f3eb5ff
1 changed files with 439 additions and 98 deletions

View File

@ -1,23 +1,27 @@
// In our world, you cannot tell whether you are moving or not.
// In the world of HyperRogue,
// some CA suggestions:
// https://www.quora.com/Are-there-variations-of-Conways-Game-of-Life-based-upon-a-triangular-or-hexagonal-grid
// https://arunarjunakani.github.io/HexagonalGameOfLife/
// B2 S34
// Creating a roguelike in 2+1D anti-de Sitter spacetime seems hard, so let's start with a cellular automaton. The rules are like Conway's Game of life, except that hex tile are born at 2 neighbors and overcrowded at 3. (1/5)
// ./ht srange=7 -shothud 1 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr simspeed=3 -ads-keys -ads-keylist xaxwxsxdx -ads-keylist 0 -zoom .95 -shot-1000 -animvideo 1800 ads-ca.mp4
// ./hyper ads_srange=7 -shothud 1 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr ads_simspeed=3 -ads-keys -ads-keylist xaxwxsxdx -ads-keylist 0 -zoom .95 -shot-1000 -animvideo 1800 ads-ca.mp4
// However, it takes 4 iterations for neighbors (brown) to affect a cell (red). (Information cannot travel faster than c -- with <4 iterations cells would depend on their own future.) The blue 'plague' shows which cells are affected by the original source. (2/5)
// ./ht plague=221 srange=7 -shothud 1 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr simspeed=3 -ads-keys -ads-keylist xaxwxsxdx -ads-keylist 0 -zoom .95 -shot-1000 -ads-highlight -animvideo 1800 ads-ca-plague.mp4 -exit
// ./hyper ads_plague=221 ads_srange=7 -shothud 1 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr ads_simspeed=3 -ads-keys -ads-keylist xaxwxsxdx -ads-keylist 0 -zoom .95 -shot-1000 -ads-highlight -animvideo 1800 ads-ca-plague.mp4 -exit
// Here is how the situation changes when we don't just sit on a star and try to travel. In this viz we see the situation "at the current time" (of course IRL we would see the past states). (It is more fun to play with when you can control it manually, of course.) (3/5)
// ./hyper ads_accel=20 ads_srange=7 -shothud 1 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr ads_simspeed=6 -ads-keys -ads-keylist xaxwxxxxxaxwx -zoom .95 -shot-1000 -animvideo 3600 ads-ca-move.mp4 -exit
// (Why would we want a roguelike in adS spacetime? In our world we do not feel whether we are moving on not; in the world of HyperRogue, this is not the case. https://twitter.com/ZenoRogue/status/1418957609269440512) (4/5)
// (This why in HyperRogue we have long but narrow snakes, and ivies which grow, but nothing wider than a Kraken could move. This is because in HyperRogue time is added in in Euclidean way; anti-de Sitter spacetime adds time to the hyperbolic plane in a "better" way.) (5/5)
// [https://twitter.com/ZenoRogue/status/1538874019948150790] Actually it would not remain in the same space (i.e., that is not a timelike geodesic) -- see the star in the center of the simulation here, it starts without movement relative to C (unmarked center), but then "wobbles". [This animation is faster than the ones in the thread]
// ./hyper -shothud 1 ads_srange=7 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr -ads-keys -run ads_simspeed="2*pi" -zoom .95 -shot-1000 -animvideo 1800 ads-ca-faster.mp4 -exit
// [https://twitter.com/ZenoRogue/status/1539871748950315010] However, we could render the hyperbolic plane using Beltrami-Klein projection (as below, contrary to Poincar in other animations), then Beltrami-Klein stretching counterbalances the Lorentz contraction and we get (rotating) hyperbolic plane in Poincar model.
// ./hyper ads_srange=7 -shothud 1 -csc .4 -rotspace -canvas-random 10 -prodperiod 0 -ads-ca-check -ads-ca-view -noscr ads_simspeed=3 -ads-keys -ads-keylist xaxwxsxdx -ads-keylist 0 -zoom .95 -shot-1000 -alpha 0 -animvideo 1800 ads-ca-klein.mp4
#include "../rogueviz/rogueviz.h"
@ -35,6 +39,8 @@ ld sqf = sq;
int lim = 10;
int dispmode;
struct star {
hyperpoint a;
hyperpoint b;
@ -43,6 +49,12 @@ struct star {
vector<star> stars;
ld simspeed = 0;
ld accel = 6;
/* how many steps to generate */
int numsteps = 1000;
bool ord(hyperpoint a, hyperpoint b) {
for(int i=0; i<4; i++) if(a[i] != b[i]) return a[i] > b[i];
return false;
@ -111,24 +123,60 @@ transmatrix lorentz(int a, int b, ld v) {
return T;
}
transmatrix current = Id;
shiftmatrix current = shiftless(Id);
void draw_ads() {
ld t = ticks / anims::period * 2 * M_PI;
/* this is uzpush(-x) */
transmatrix chg_shift(ld x) {
return cspin(2, 3, x) * cspin(0, 1, x);
}
char forcekey;
shiftmatrix apply_lorentz(shiftmatrix S, transmatrix lor) {
S.T = chg_shift(-S.shift) * lor * chg_shift(S.shift) * S.T;
return S;
}
string keylist = "0"; // xaxdxsxwx";
ld ang = 0;
bool acc = false;
void pass_time() {
ld t = ticks / anims::period;
static ld last_t = t;
if(t < last_t) last_t = 0;
no_find_player = true;
if(1) {
dynamicval<eGeometry> g(geometry, gCubeTiling);
current = cspin(2, 3, t - last_t) * current;
char forcekey = keylist[frac(t) * isize(keylist)];
acc = false;
if(true) {
ld delta = t - last_t;
dynamicval<eGeometry> g(geometry, geometry == gRotSpace ? geometry : gCubeTiling);
const Uint8 *keystate = SDL12_GetKeyState(NULL);
if(keystate['a'] || forcekey == 'a') current = apply_lorentz(current, lorentz(0, 2, delta*accel)), ang = 180, acc = true;
if(keystate['d'] || forcekey == 'd') current = apply_lorentz(current, lorentz(0, 2, -delta*accel)), ang = 0, acc = true;
if(keystate['w'] || forcekey == 'w') current = apply_lorentz(current, lorentz(1, 2, delta*accel)), ang = 90, acc = true;
if(keystate['s'] || forcekey == 's') current = apply_lorentz(current, lorentz(1, 2, -delta*accel)), ang = 270, acc = true;
current.T = cspin(3, 2, delta * simspeed) * current.T;
optimize_shift(current);
hassert(eqmatrix(chg_shift(current.shift) * current.T, unshift(current)));
}
last_t = t;
}
void draw_ads() {
pass_time();
if(stars.empty()) for(hyperpoint h: hs) {
hyperpoint h1;
if(1) {
dynamicval<eGeometry> g(geometry, gCubeTiling);
h1 = current * h;
h1 = unshift(current * h);
}
hyperpoint h2 = h1; h2[2] = sqrt(h2[2] * h2[2] + h2[3] * h2[3]);
if(h1[2] < 0) continue;
@ -143,8 +191,8 @@ void draw_ads() {
if(1) {
dynamicval<eGeometry> g(geometry, gCubeTiling);
hyperpoint h1 = current * st.a;
hyperpoint h2 = current * st.b;
hyperpoint h1 = unshift(current * st.a);
hyperpoint h2 = unshift(current * st.b);
hm = h1 * h2[3] - h2 * h1[3];
ld d = hypot(h2[3], h1[3]);
if(d == 0) continue;
@ -159,79 +207,127 @@ void draw_ads() {
bool handleKey(int sym, int uni) {
dynamicval<eGeometry> g(geometry, gCubeTiling);
if(uni == 'a') { current = lorentz(0, 3, +.1) * current; return true; }
if(uni == 'd') { current = lorentz(0, 3, -.1) * current; return true; }
if(uni == 'w') { current = lorentz(1, 3, +.1) * current; return true; }
if(uni == 's') { current = lorentz(1, 3, -.1) * current; return true; }
println(hlog, simspeed);
if(uni == 'p') { simspeed += .01; return true; }
if(uni == 'b') { simspeed -= .01; return true; }
if(uni == 'z') { simspeed = 0; return true; }
if(uni == 'x') { dispmode++; dispmode %= 4; return true; }
if(among(uni, 'a', 'd', 's', 'w')) return true;
if(uni == 'j') { current = apply_lorentz(current, lorentz(0, 3, .1)); return true; }
if(uni == 'l') { current = apply_lorentz(current, lorentz(0, 3, -.1)); return true; }
if(uni == 'i') { current = apply_lorentz(current, lorentz(1, 3, .1)); return true; }
if(uni == 'k') { current = apply_lorentz(current, lorentz(1, 3, -.1)); return true; }
/*
if(uni == 'a') { current = apply_lorentz(current, lorentz(0, 2, +.1)); return true; }
if(uni == 'd') { current = apply_lorentz(current, lorentz(0, 2, -.1)); return true; }
if(uni == 'w') { current = apply_lorentz(current, lorentz(1, 2, +.1)); return true; }
if(uni == 's') { current = apply_lorentz(current, lorentz(1, 2, -.1)); return true; } */
return false;
}
void run_ads() {
rogueviz::rv_hook(hooks_frame, 100, draw_ads);
rogueviz::rv_hook(hooks_handleKey, 0, handleKey);
}
void auto_shift() {
current = spin(30*degree) * lorentz(0, 3, 1) * spin(-30*degree) * current;
current.T = spin(30*degree) * lorentz(0, 3, 1) * spin(-30*degree) * current.T;
}
/* in our cellular automaton, each tile is affected by its own history, and the spatial neighbors of its ms-step history */
/* ms==3 works for {7,3}; ms==4 works for bitruncated {7,3} */
int ms = 4;
/* the simulation range for the CA */
int srange = 5;
/* (c1,k) in causality(c) means that get_at(c,n) is affected by get_at(c1,n-k) */
map<cell*, vector<pair<cell*, int>> > causality;
map<cell*, int> cell_id;
set<cell*> cs;
int ms = 4;
int srange = 7;
/* for every fiber f, where_matrix[f] equals ggmatrix(get_at(f, base_level[f])) */
map<cell*, shiftmatrix> where_matrix;
map<cell*, int> base_level;
void check(cell *c, const shiftmatrix& S) {
auto p = hybrid::get_where(c);
if(causality.count(p.first)) return;
auto& caus = causality[p.first];
auto c1 = c;
shiftmatrix S1 = S;
for(int i=0; i<ms; i++) {
c1 = c1->cmove(c->type - 2);
S1 = S1 * currentmap->adj(c1, c->type-2);
vector<pair<cell*, shiftmatrix>> checklist;
cell *pc0;
void check_all() {
for(int i=0; i<isize(checklist); i++) {
auto c = checklist[i].first;
auto S = checklist[i].second;
auto p = hybrid::get_where(c);
if(causality.count(p.first)) continue;
auto& caus = causality[p.first];
auto c1 = c;
optimize_shift(S);
shiftmatrix S1 = S;
// println(hlog, "we are : ", kz(S), " plevel = ", cgi.plevel);
for(int i=0; i<ms; i++) {
c1 = c1->cmove(c->type - 2);
S1 = S1 * currentmap->adj(c1, c->type-2);
optimize_shift(S1);
// println(hlog, "below : ", kz(S1));
}
where_matrix[p.first] = S;
base_level[p.first] = p.second;
hybrid::in_underlying_geometry([&] {
setdist(p.first, 4, nullptr);
p.first->land = laIce;
});
// hybrid::test_at(p.first);
// time increases
auto p1 = hybrid::get_where(c1);
hassert(p1.second == p.second - ms);
for(int i=0; i<c->type-2; i++) {
cell *c2 = c1->cmove(i);
auto p2 = hybrid::get_where(c2);
bool ok;
hybrid::in_underlying_geometry([&] {
ok = celldist(p2.first) <= srange;
});
if(!ok) continue;
caus.emplace_back(p2.first, p.second - p2.second);
// (p,x) (p2,0) -> okay
// minimum p1 above p2
if(0) {
shiftmatrix below = S1 * currentmap->adj(c1, i);
optimize_shift(below);
println(hlog, "for ", c->move(i));
println(hlog, "matrix below is: ", kz(below));
below = S * currentmap->adj(c1, i);
optimize_shift(below);
println(hlog, "matrix here is: ", kz(below));
}
// go below
checklist.emplace_back(c2, S1 * currentmap->adj(c1, i));
// keep level
// checklist.emplace_back(c->move(i), S * currentmap->adj(c1, i));
}
println(hlog, "for ", p.first, " base level is ", p.second, " and causality is ", caus);
}
where_matrix[p.first] = S;
hybrid::in_underlying_geometry([&] {
setdist(p.first, 4, nullptr);
p.first->land = laIce;
});
hybrid::test_at(p.first);
// time increases
auto p1 = hybrid::get_where(c1);
println(hlog, p.second, " -> ", p1.second);
for(int i=0; i<c->type-2; i++) {
cell *c2 = c1->cmove(i);
auto p2 = hybrid::get_where(c2);
bool ok = cs.count(p2.first);
hybrid::in_underlying_geometry([&] {
ok = celldist(p2.first) <= srange;
});
if(!ok) continue;
caus.emplace_back(p2.first, p.second - p2.second);
// (p,x) (p2,0) -> okay
// minimum p1 above p2
check(c2, S1 * currentmap->adj(c1, i));
}
}
/* {get_at(f,noncausal[f]): fiber f} is a set of cells such that none depends on any other */
map<cell*, int> noncausal;
bool randlive() { return hrand(100) < 20 ? 1 : 0; }
vector<cell*> compute_order;
/* inverse of compute_order */
map<cell*, int> index;
/* in each iteration i, for every k (increasing), we compute the state of get_where(compute_order[k], noncausal[k]+i) */
/* this is ca_state[i][k]; we never refer to states where (i,k) is greater this way */
vector<vector<int>> ca_states;
vector<vector<pair<int, int>>> relative;
int plague = -1;
void fine() {
compute_order.clear();
index.clear();
@ -250,6 +346,7 @@ void fine() {
if(ok) {
to_remove.push_back(u);
noncausal[u]++;
println(hlog, "set noncausal of ", u, " to ", noncausal[u]);
}
}
if(to_remove.empty()) { println(hlog, "failed to remove"); return; }
@ -258,7 +355,8 @@ void fine() {
int ids = 0;
for(auto& p: compute_order) index[p] = ids++;
vector<vector<pair<int, int>>> relative(ids);
relative.clear();
relative.resize(ids);
for(auto p: compute_order) {
int i = index[p];
for(auto& pp: causality[p]) {
@ -275,8 +373,6 @@ void fine() {
vector<int> noncausal_indexed(ids);
for(auto& p: compute_order) noncausal_indexed.push_back(noncausal[p]);
vector<vector<int>> ca_states;
println(hlog, "generating initial random");
for(int t=0; t<ms; t++) {
ca_states.emplace_back();
@ -286,9 +382,8 @@ void fine() {
vector<int> lifecounts;
int steps = 50;
int steps = numsteps;
for(int t=ms; t<steps; t++) {
println(hlog, "generating step t=", t);
ca_states.emplace_back();
ca_states.back().resize(ids);
int countlife = 0;
@ -304,10 +399,16 @@ void fine() {
continue;
}
for(int i=0; i<unknown_neighbors[j]; i++) lives += randlive();
int old = ca_states[t-ms][j];
int newstate;
if(old == 0) newstate = lives == 2 ? 1 : 0;
if(old == 1) newstate = (lives == 3 || lives == 4) ? 1 : 0;
int old = ca_states[t-1][j];
int newstate = old;
if(isize(relative[j]) + unknown_neighbors[j] == 6 && lives >= 2) lives++;
if(old == 0) newstate = lives == 3 ? 1 : 0;
if(old == 1) newstate = (lives == 3 || lives == 2) ? 1 : 0;
if(lives >= 10) newstate = 10;
if(j == index[pc0] && t == plague) {
println(hlog, "set 10 at ", tie(j, t));
newstate = 10;
}
ca_states[t][j] = newstate;
countlife += newstate;
}
@ -341,17 +442,12 @@ void reset_to_underlying(cell *where) {
void ads_ca_check() {
auto pc = hybrid::get_where(cwt.at).first;
hybrid::in_underlying_geometry([&] {
cs.insert(pc);
cs.insert(pc->cmove(0));
cs.insert(pc->cmove(1));
});
for(auto cc: cs)
println(hlog, "SET = ", cc);
pc0 = pc;
check(cwt.at, shiftless(Id));
checklist.emplace_back(cwt.at, shiftless(Id));
check_all();
println(hlog, causality);
println(hlog, "causality is: ", causality);
// at step t, for (c,i) in noncausal, change (c,i+t)
for(auto p: causality) noncausal[p.first] = 0;
vector<int> ncs;
@ -411,32 +507,263 @@ void ads_ca_check() {
reset_to_underlying(x1);
}
hyperpoint findflat(shiftpoint S0) {
hyperpoint h = S0.h;
ld at = atan2(h[3], h[2]);
h = cspin(2, 3, at) * cspin(0, 1, at) * h;
return h;
ld get_shift_cycles(ld shift) {
return floor(shift / 2 / M_PI + .5) * 2 * M_PI;
}
shiftpoint shift_perfect_mul(shiftmatrix T, shiftpoint h) {
ld sh = get_shift_cycles(h.shift);
h.shift -= sh;
shiftpoint res;
for(int i=0; i<=10; i++) {
shiftpoint cand = T * chg_shift(h.shift * i / 10.) * h.h;
// println(hlog, "shift check: ", eqmatrix(chg_shift(current.shift) * current.T, unshift(current)));
optimize_shift(cand);
if(i > 0) {
while(cand.shift > res.shift + M_PI) cand.shift -= 2 * M_PI;
while(cand.shift < res.shift - M_PI) cand.shift += 2 * M_PI;
}
res = cand;
}
res.shift += sh;
return res;
}
shiftpoint bshift(shiftpoint h, ld sh) {
h.shift += sh; return h;
}
struct flatresult {
hyperpoint h;
ld shift;
};
flatresult findflat(shiftpoint h) {
optimize_shift(h);
shiftpoint hz = shift_perfect_mul(current, h);
ld d = binsearch(-M_PI - hz.shift, M_PI - hz.shift, [&] (ld x) { return shift_perfect_mul(current, bshift(h, x)).shift > 0; }, 20);
shiftpoint h1 = shift_perfect_mul(current, bshift(h, d));
if(abs(h1.shift) > .1) {
println(hlog, "h=", h, " current=", current);
println(hlog, "shift = ", h1.shift, " for d = ", d, " h1 = ", h1);
for(ld d=-10; d<=10; d+=.5)
println(hlog, "for d = ", d, " h1 = ", kz(shift_perfect_mul(current, bshift(h, d))));
exit(1);
}
hyperpoint h2 = h1.h;
tie(h2[2], h2[3]) = make_pair(h2[3], -h2[2]);
return flatresult{h2, d};
/*
hyperpoint h = unshift(S0);
transmatrix deg90 = cspin(2, 3, 90*degree) * cspin(0, 1, 90*degree);
hyperpoint h0 = unshift(current) * h;
hyperpoint h90 = unshift(current) * deg90 * h;
// h = h0 * cos(t) + h90 * sin(t)
// 0 == h0[3] * cos(t) + h90[3] * sin(t);
// 0 == h0[3] + h90[3] * tan(t);
ld cost, sint, tant;
ld t;
if(h90[3]) {
tant = - h0[3] / h90[3];
cost = 1 / sqrt(1 + tant * tant);
sint = tant * cost;
t = atan2(sint, cost);
}
else {
cost = 0;
sint = 1;
t = 90*degree;
}
hyperpoint h2 = h0 * cost + h90 * sint;
if(h2[2] < 0) { h2 = -h2; t += M_PI; }
if(0) {
ld at = atan2(h[3], h[2]);
hyperpoint h1 = cspin(2, 3, at) * cspin(0, 1, at) * h;
println(hlog, h2, " vs ", h1);
if(sqhypot_d(4, h2-h1) > 1) {
println(hlog, "h = ", kz(h));
println(hlog, "h0 = ", kz(h0));
println(hlog, "h90 = ", kz(h90));
println(hlog, "tant = ", tant);
println(hlog, "cost = ", cost);
println(hlog, "sint = ", sint);
println(hlog, "at = ", at, " : ", make_tuple(cos(at), sin(at), tan(at)));
println(hlog, "h1 = ", kz(h1));
println(hlog, "h2 = ", kz(h2));
exit(1);
}
}
return {h2, current.shift + t + cycles};
*/
}
ld fracc(ld x) {
x -= floor(x);
if(x < .2) return ilerp(0, .2, x);
if(x > .8) return ilerp(1, .8, x);
return 1;
}
int who = -1;
bool view_ads_ca() {
pass_time();
auto plev = cgi.plevel; /* we are in another CGI so we have no access to that... */
if(1) {
dynamicval<eGeometry> g(geometry, gNormal);
dynamicval<eModel> p(pmodel, mdDisk);
println(hlog, "zoom = ", pconf.scale);
check_cgi();
initquickqueue();
println(hlog, "curvedata size = ", isize(curvedata), " curvestart = ", curvestart);
calcparam();
clearaura();
for(int i=0; i<isize(compute_order); i++) {
hyperpoint h;
cell *c = compute_order[i];
auto findflat_decode = [&] (shiftpoint h) {
flatresult x = findflat(h);
x.shift = base_level[c] + .5 + x.shift / plev - noncausal[c];
return x;
};
flatresult center;
vector<flatresult> hlist;
color_t statecolor;
if(1) {
dynamicval<eGeometry> b(geometry, gCubeTiling);
cell *c = compute_order[i];
dynamicval<eGeometry> b(geometry, gRotSpace);
shiftmatrix S = where_matrix[c];
h = findflat(S * C0);
for(int i=0; i<=c->type; i++) {
hyperpoint ha = hybrid::get_corner(c, i, 2, 0);
hlist.push_back(findflat_decode(S * ha));
}
center = findflat_decode(S * C0);
}
queuepoly(shiftless(rgpushxto0(h)), cgi.shGem[0], 0xFFD500FF);
// queuepolyat(shiftless(rgpushxto0(h)), cgi.shGem[0], 0xFFD500FF, PPR::LINE);
auto get_statecolor = [&] (int t) {
if(t < 0) return 0xFF0000FFu;
else if(t >= isize(ca_states)) return 0xFF00FFFFu;
else {
if(who != -1) {
if(i == who && (t & 15) == 0)
return 0xFF0000u;
if(i == who && (t & 15) == 15)
return 0xFFC000u;
for(auto xx: relative[who])
if(xx.first == i && (((t-xx.second)&15) == 0))
return 0xFF8000u;
}
if(ca_states[t][i] == 2)
return 0xFF0000u;
else if(ca_states[t][i] == 10)
return 0x2020F0u;
else if(ca_states[t][i] == 1)
return 0xFFFF40u;
else
return 0x808080u;
}
};
ld minv = hlist[0].shift;
ld maxv = hlist[0].shift;
for(auto& h: hlist) {
ld v = h.shift;
if(v < minv) minv = v;
if(v > maxv) maxv = v;
}
if(1) {
for(int v=floor(minv); v<maxv+1; v++) {
auto draw_slice = [&] (ld a, ld b, color_t col) {
vector<hyperpoint> slice;
for(int i=0; i<c->type; i++) {
if(hlist[i].shift >= a && hlist[i].shift <= b)
slice.push_back(hlist[i].h);
if((hlist[i].shift < a) ^ (hlist[i+1].shift < a)) {
ld p = ilerp(hlist[i].shift, hlist[i+1].shift, a);
hyperpoint h1 = lerp(hlist[i].h, hlist[i+1].h, p);
slice.push_back(h1);
}
if((hlist[i].shift > b) ^ (hlist[i+1].shift > b)) {
ld p = ilerp(hlist[i].shift, hlist[i+1].shift, b);
hyperpoint h1 = lerp(hlist[i].h, hlist[i+1].h, p);
slice.push_back(h1);
}
if(hlist[i+1].shift < a && hlist[i].shift > b)
swap((&slice.back())[-1], slice.back());
}
if(isize(slice) < 3) return;
for(auto e: slice) curvepoint(e);
curvepoint(slice[0]);
queuecurve(shiftless(Id), 0, col, PPR::LINE);
};
draw_slice(v-.1, v+.1, 0xFF);
draw_slice(v+.1, v+.9, (gradient(0, get_statecolor(v), 0, .5, 1) << 8) | 0xFF);
}
addaura(shiftless(center.h), get_statecolor(center.shift), 0);
}
for(auto& p: hlist) curvepoint(p.h);
queuecurve(shiftless(Id), 0xFFFFFFFF, 0, PPR::LINE);
switch(dispmode) {
case 0: {
int bri = fracc(center.shift) * 255;
color_t stat = get_statecolor(center.shift);
color_t col = (stat << 8) | bri;
poly_outline = (stat << 8) | (bri/2);
queuepoly(shiftless(rgpushxto0(center.h)), cgi.shGem[ctof(c)], col);
break;
}
case 1: {
string str = its(floor(center.shift));
queuestr(shiftless(rgpushxto0(center.h)), .3, str, gradient(0, 0xFFFFFF, 0, fracc(center.shift), 1), 8);
break;
}
case 2: {
string str = fts(center.shift); // str = lalign(0,c);
queuestr(shiftless(rgpushxto0(center.h)), .3, str, gradient(0, 0xFFFFFF, 0, fracc(center.shift), 1), 8);
break;
}
case 3: {
string str = lalign(0,c);
queuestr(shiftless(rgpushxto0(center.h)), .3, str, gradient(0, 0xFFFFFF, 0, fracc(center.shift), 1), 8);
break;
}
}
addaura(shiftless(center.h), statecolor, 0);
}
if(acc) {
poly_outline = 0xFF;
queuepolyat(shiftless(spin(ang*degree) * Id), cgi.shEagle, 0x2020FFFF, PPR::LINE);
}
quickqueue();
drawaura();
}
check_cgi();
println(hlog, "plev = ", plev);
return true;
}
@ -446,8 +773,22 @@ void run_ads_ca_view() {
rogueviz::rv_hook(hooks_prestats, 100, view_ads_ca);
}
auto shot_hooks = arg::add3("-ads", run_ads) + arg::add3("-ads-rat", gen_rational) + arg::add3("-ads-stars", gen_stars) + arg::add3("-ads-get", gen_get) + arg::add3("-ads-shift", auto_shift)
+ arg::add3("-ads-ca-check", ads_ca_check) + arg::add3("-ads-ca-view", run_ads_ca_view);
auto shot_hooks =
arg::add3("-ads-display", [] { rogueviz::rv_hook(hooks_frame, 100, draw_ads); })
+ arg::add3("-ads-keys", [] { rogueviz::rv_hook(hooks_handleKey, 0, handleKey); })
+ arg::add3("-ads-rat", gen_rational) + arg::add3("-ads-stars", gen_stars) + arg::add3("-ads-get", gen_get) + arg::add3("-ads-shift", auto_shift)
+ arg::add3("-ads-ca-check", ads_ca_check) + arg::add3("-ads-ca-view", run_ads_ca_view)
+ arg::add3("-ads-keylist", [] { arg::shift(); keylist = arg::args(); })
+ arg::add3("-ads-highlight", [] { who = index[pc0]; })
+ addHook(hooks_configfile, 100, [] {
param_f(simspeed, "ads_simspeed");
param_f(accel, "ads_accel");
param_i(dispmode, "ads_dispmode");
param_i(srange, "ads_srange");
param_i(plague, "ads_plague");
param_i(numsteps, "ads_numsteps");
param_i(ms, "ads_ms");
});
}
}