mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
Merge branch 'master' into fix_hyperroid
This commit is contained in:
commit
28383c94e0
@ -89,8 +89,6 @@ struct archimedean_tiling {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CAP_ARCM
|
|
||||||
|
|
||||||
#if HDR
|
#if HDR
|
||||||
static const int sfPH = 1;
|
static const int sfPH = 1;
|
||||||
static const int sfLINE = 2;
|
static const int sfLINE = 2;
|
||||||
@ -99,6 +97,8 @@ static const int sfTHREE = 8;
|
|||||||
static const int sfSEMILINE = 16;
|
static const int sfSEMILINE = 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CAP_ARCM
|
||||||
|
|
||||||
EX archimedean_tiling current;
|
EX archimedean_tiling current;
|
||||||
EX archimedean_tiling fake_current;
|
EX archimedean_tiling fake_current;
|
||||||
|
|
||||||
@ -841,8 +841,8 @@ void connectHeptagons(heptspin hi, heptspin hs) {
|
|||||||
|
|
||||||
/** T and X are supposed to be equal -- move T so that it is closer to X */
|
/** T and X are supposed to be equal -- move T so that it is closer to X */
|
||||||
void fixup_matrix(transmatrix& T, const transmatrix& X, ld step) {
|
void fixup_matrix(transmatrix& T, const transmatrix& X, ld step) {
|
||||||
for(int i=0; i<MDIM; i++)
|
for(int i=0; i<MXDIM; i++)
|
||||||
for(int j=0; j<MDIM; j++)
|
for(int j=0; j<MXDIM; j++)
|
||||||
T[i][j] = (T[i][j] * (1-step) + X[i][j] * step);
|
T[i][j] = (T[i][j] * (1-step) + X[i][j] * step);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1450,10 +1450,10 @@ EX int valence() {
|
|||||||
return total / isize(current.faces);
|
return total / isize(current.faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EX map<gp::loc, cdata>& get_cdata() { return ((arcm::hrmap_archimedean*) (currentmap))->eucdata; }
|
EX map<gp::loc, cdata>& get_cdata() { return ((arcm::hrmap_archimedean*) (currentmap))->eucdata; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
EX }
|
EX }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,8 +136,8 @@ EX transmatrix adjmatrix(int i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct hrmap_asonov : hrmap {
|
struct hrmap_asonov : hrmap {
|
||||||
unordered_map<coord, heptagon*> at;
|
map<coord, heptagon*> at;
|
||||||
unordered_map<heptagon*, coord> coords;
|
map<heptagon*, coord> coords;
|
||||||
|
|
||||||
heptagon *getOrigin() override { return get_at(coord(0,0,0)); }
|
heptagon *getOrigin() override { return get_at(coord(0,0,0)); }
|
||||||
|
|
||||||
|
22
attack.cpp
22
attack.cpp
@ -372,7 +372,7 @@ EX bool attackJustStuns(cell *c2, flagtype f, eMonster attacker) {
|
|||||||
return true;
|
return true;
|
||||||
else if((f & AF_SWORD) && c2->monst == moSkeleton)
|
else if((f & AF_SWORD) && c2->monst == moSkeleton)
|
||||||
return false;
|
return false;
|
||||||
else if(f & (AF_CRUSH | AF_MAGIC | AF_FALL | AF_EAT | AF_GUN))
|
else if(f & (AF_CRUSH | AF_MAGIC | AF_FALL | AF_EAT | AF_GUN | AF_PSI))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return isStunnable(c2->monst) && c2->hitpoints > 1;
|
return isStunnable(c2->monst) && c2->hitpoints > 1;
|
||||||
@ -1183,19 +1183,19 @@ EX void killThePlayerAt(eMonster m, cell *c, flagtype flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HDR
|
#if HDR
|
||||||
template<class T> void do_swords(cell *mf, cell *mt, eMonster who, const T& f) {
|
template<class T> void do_swords(movei mi, eMonster who, const T& f) {
|
||||||
for(int bb=0; bb<2; bb++) if(who == moPlayer && sword::orbcount(bb)) {
|
for(int bb=0; bb<2; bb++) if(who == moPlayer && sword::orbcount(bb)) {
|
||||||
cell *sf = sword::pos(mf, sword::dir[multi::cpid], bb);
|
cell *sf = sword::pos(mi.s, sword::dir[multi::cpid], bb);
|
||||||
cell *st = sword::pos(mt, sword::shift(mf, mt, sword::dir[multi::cpid]), bb);
|
cell *st = sword::pos(mi.t, sword::shift(mi, sword::dir[multi::cpid]), bb);
|
||||||
f(st, bb);
|
f(st, bb);
|
||||||
if(sf != st && !isNeighbor(sf,st)) {
|
if(sf != st && !isNeighbor(sf,st)) {
|
||||||
// also attack the in-transit cell
|
// also attack the in-transit cell
|
||||||
if(S3 == 3) {
|
if(S3 == 3) {
|
||||||
forCellEx(sb, sf) if(isNeighbor(sb, st) && sb != mf && sb != mt) f(sb, bb);
|
forCellEx(sb, sf) if(isNeighbor(sb, st) && sb != mi.s && sb != mi.t) f(sb, bb);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
forCellEx(sb, mf) if(isNeighbor(sb, st) && sb != mt) f(sb, bb);
|
forCellEx(sb, mi.s) if(isNeighbor(sb, st) && sb != mi.t) f(sb, bb);
|
||||||
forCellEx(sb, mt) if(isNeighbor(sb, sf) && sb != mf) f(sb, bb);
|
forCellEx(sb, mi.t) if(isNeighbor(sb, sf) && sb != mi.s) f(sb, bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1204,14 +1204,16 @@ template<class T> void do_swords(cell *mf, cell *mt, eMonster who, const T& f) {
|
|||||||
|
|
||||||
int lastdouble = -3;
|
int lastdouble = -3;
|
||||||
|
|
||||||
EX void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill IS(0)) {
|
EX void stabbingAttack(movei mi, eMonster who, int bonuskill IS(0)) {
|
||||||
int numsh = 0, numflail = 0, numlance = 0, numslash = 0, numbb[2];
|
int numsh = 0, numflail = 0, numlance = 0, numslash = 0, numbb[2];
|
||||||
|
|
||||||
numbb[0] = numbb[1] = 0;
|
numbb[0] = numbb[1] = 0;
|
||||||
|
|
||||||
int backdir = neighborId(mt, mf);
|
cell *mf = mi.s;
|
||||||
|
cell *mt = mi.t;
|
||||||
|
int backdir = mi.rev_dir();
|
||||||
|
|
||||||
do_swords(mf, mt, who, [&] (cell *c, int bb) { if(swordAttack(mt, who, c, bb)) numbb[bb]++, numslash++; });
|
do_swords(mi, who, [&] (cell *c, int bb) { if(swordAttack(mt, who, c, bb)) numbb[bb]++, numslash++; });
|
||||||
|
|
||||||
for(int bb=0; bb<2; bb++) achievement_count("SLASH", numbb[bb], 0);
|
for(int bb=0; bb<2; bb++) achievement_count("SLASH", numbb[bb], 0);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ struct display_data {
|
|||||||
/** The view relative to the player character. */
|
/** The view relative to the player character. */
|
||||||
shiftmatrix player_matrix;
|
shiftmatrix player_matrix;
|
||||||
/** On-screen coordinates for all the visible cells. */
|
/** On-screen coordinates for all the visible cells. */
|
||||||
unordered_map<cell*, shiftmatrix> cellmatrices, old_cellmatrices;
|
map<cell*, shiftmatrix> cellmatrices, old_cellmatrices;
|
||||||
/** Position of the current map view, relative to the screen (0 to 1). */
|
/** Position of the current map view, relative to the screen (0 to 1). */
|
||||||
ld xmin, ymin, xmax, ymax;
|
ld xmin, ymin, xmax, ymax;
|
||||||
/** Position of the current map view, in pixels. */
|
/** Position of the current map view, in pixels. */
|
||||||
@ -50,7 +50,7 @@ struct display_data {
|
|||||||
/** Which copy of the player cell? */
|
/** Which copy of the player cell? */
|
||||||
transmatrix which_copy;
|
transmatrix which_copy;
|
||||||
/** On-screen coordinates for all the visible cells. */
|
/** On-screen coordinates for all the visible cells. */
|
||||||
unordered_map<cell*, vector<shiftmatrix>> all_drawn_copies;
|
map<cell*, vector<shiftmatrix>> all_drawn_copies;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define View (::hr::current_display->view_matrix)
|
#define View (::hr::current_display->view_matrix)
|
||||||
@ -79,7 +79,14 @@ int utfsize(char c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX int get_sightrange() { return getDistLimit() + sightrange_bonus; }
|
EX int get_sightrange() { return getDistLimit() + sightrange_bonus; }
|
||||||
EX int get_sightrange_ambush() { return max(get_sightrange(), ambush::distance); }
|
|
||||||
|
EX int get_sightrange_ambush() {
|
||||||
|
#if CAP_COMPLEX2
|
||||||
|
return max(get_sightrange(), ambush::distance);
|
||||||
|
#else
|
||||||
|
return get_sightrange();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool display_data::in_anaglyph() { return vid.stereo_mode == sAnaglyph; }
|
bool display_data::in_anaglyph() { return vid.stereo_mode == sAnaglyph; }
|
||||||
bool display_data::stereo_active() { return vid.stereo_mode != sOFF; }
|
bool display_data::stereo_active() { return vid.stereo_mode != sOFF; }
|
||||||
@ -603,7 +610,9 @@ EX void resetGL() {
|
|||||||
matched_programs.clear();
|
matched_programs.clear();
|
||||||
glhr::current_glprogram = nullptr;
|
glhr::current_glprogram = nullptr;
|
||||||
ray::reset_raycaster();
|
ray::reset_raycaster();
|
||||||
|
#if CAP_RUG
|
||||||
if(rug::glbuf) rug::close_glbuf();
|
if(rug::glbuf) rug::close_glbuf();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -1142,8 +1151,7 @@ EX void initgraph() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ISWEB
|
#if ISWEB
|
||||||
vid.xscr = vid.xres = 1280;
|
get_canvas_size();
|
||||||
vid.yscr = vid.yres = 900;
|
|
||||||
#else
|
#else
|
||||||
const SDL_VideoInfo *inf = SDL_GetVideoInfo();
|
const SDL_VideoInfo *inf = SDL_GetVideoInfo();
|
||||||
vid.xscr = vid.xres = inf->current_w;
|
vid.xscr = vid.xres = inf->current_w;
|
||||||
@ -1161,7 +1169,9 @@ EX void initgraph() {
|
|||||||
#if CAP_CONFIG
|
#if CAP_CONFIG
|
||||||
loadConfig();
|
loadConfig();
|
||||||
#endif
|
#endif
|
||||||
|
#if CAP_ARCM
|
||||||
arcm::current.parse();
|
arcm::current.parse();
|
||||||
|
#endif
|
||||||
if(hybri) geometry = hybrid::underlying;
|
if(hybri) geometry = hybrid::underlying;
|
||||||
|
|
||||||
#if CAP_COMMANDLINE
|
#if CAP_COMMANDLINE
|
||||||
|
@ -21,6 +21,7 @@ EX int newRoundTableRadius() {
|
|||||||
return 28 + 2 * items[itHolyGrail];
|
return 28 + 2 * items[itHolyGrail];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CAP_COMPLEX2
|
||||||
EX int getAnthraxData(cell *c, bool b) {
|
EX int getAnthraxData(cell *c, bool b) {
|
||||||
int d = celldistAlt(c);
|
int d = celldistAlt(c);
|
||||||
int rad = 28 + 3 * camelot::anthraxBonus;
|
int rad = 28 + 3 * camelot::anthraxBonus;
|
||||||
@ -36,10 +37,13 @@ EX int getAnthraxData(cell *c, bool b) {
|
|||||||
if(b) return rad;
|
if(b) return rad;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
EX int roundTableRadius(cell *c) {
|
EX int roundTableRadius(cell *c) {
|
||||||
if(eubinary) return 28;
|
if(eubinary) return 28;
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(tactic::on) return getAnthraxData(c, true);
|
if(tactic::on) return getAnthraxData(c, true);
|
||||||
|
#endif
|
||||||
if(!c->master->alt) return 28;
|
if(!c->master->alt) return 28;
|
||||||
return c->master->alt->alt->emeraldval & GRAIL_RADIUS_MASK;
|
return c->master->alt->alt->emeraldval & GRAIL_RADIUS_MASK;
|
||||||
}
|
}
|
||||||
@ -55,7 +59,9 @@ EX int celldistAltRelative(cell *c) {
|
|||||||
if(sphere || quotient) {
|
if(sphere || quotient) {
|
||||||
return celldist(c) - 3;
|
return celldist(c) - 3;
|
||||||
}
|
}
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(tactic::on) return getAnthraxData(c, false);
|
if(tactic::on) return getAnthraxData(c, false);
|
||||||
|
#endif
|
||||||
return celldistAlt(c) - roundTableRadius(c);
|
return celldistAlt(c) - roundTableRadius(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1805,12 +1811,14 @@ EX void moreBigStuff(cell *c) {
|
|||||||
if(c->master->emeraldval % 2)
|
if(c->master->emeraldval % 2)
|
||||||
c->wall = waColumn;
|
c->wall = waColumn;
|
||||||
}
|
}
|
||||||
|
#if CAP_BT
|
||||||
else if(geometry == gHoroTris || geometry == gHoroRec) {
|
else if(geometry == gHoroTris || geometry == gHoroRec) {
|
||||||
if(c->c.spin(bt::updir()) != 0) c->wall = waColumn;
|
if(c->c.spin(bt::updir()) != 0) c->wall = waColumn;
|
||||||
}
|
}
|
||||||
else if(geometry == gKiteDart3) {
|
else if(geometry == gKiteDart3) {
|
||||||
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
|
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if(in_s2xe()) {
|
else if(in_s2xe()) {
|
||||||
auto d = hybrid::get_where(c);
|
auto d = hybrid::get_where(c);
|
||||||
if(!PIU(pseudohept(d.first))) c->wall = waColumn;
|
if(!PIU(pseudohept(d.first))) c->wall = waColumn;
|
||||||
|
@ -18,6 +18,10 @@ EX namespace bt {
|
|||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !CAP_BT
|
||||||
|
EX int updir() { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CAP_BT
|
#if CAP_BT
|
||||||
#if HDR
|
#if HDR
|
||||||
@ -1031,7 +1035,6 @@ EX int celldistance3(heptagon *c1, heptagon *c2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX int celldistance3(cell *c1, cell *c2) { return celldistance3(c1->master, c2->master); }
|
EX int celldistance3(cell *c1, cell *c2) { return celldistance3(c1->master, c2->master); }
|
||||||
#endif
|
|
||||||
|
|
||||||
EX hyperpoint get_horopoint(ld y, ld x) {
|
EX hyperpoint get_horopoint(ld y, ld x) {
|
||||||
return xpush(-y) * bt::parabolic(x) * C0;
|
return xpush(-y) * bt::parabolic(x) * C0;
|
||||||
@ -1091,6 +1094,7 @@ EX hyperpoint get_corner_horo_coordinates(cell *c, int i) {
|
|||||||
auto hooksw = addHook(hooks_swapdim, 100, [] {
|
auto hooksw = addHook(hooks_swapdim, 100, [] {
|
||||||
if(bt::in()) build_tmatrix();
|
if(bt::in()) build_tmatrix();
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
cell.cpp
38
cell.cpp
@ -179,8 +179,11 @@ EX heptagon* hyperbolic_origin() {
|
|||||||
h.cdata = NULL;
|
h.cdata = NULL;
|
||||||
h.alt = NULL;
|
h.alt = NULL;
|
||||||
h.distance = 0;
|
h.distance = 0;
|
||||||
|
#if CAP_IRR
|
||||||
if(IRREGULAR) irr::link_start(origin);
|
if(IRREGULAR) irr::link_start(origin);
|
||||||
else h.c7 = newCell(odegree, origin);
|
else
|
||||||
|
#endif
|
||||||
|
h.c7 = newCell(odegree, origin);
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,10 +295,10 @@ EX void initcells() {
|
|||||||
|
|
||||||
hrmap* res = callhandlers((hrmap*)nullptr, hooks_newmap);
|
hrmap* res = callhandlers((hrmap*)nullptr, hooks_newmap);
|
||||||
if(res) currentmap = res;
|
if(res) currentmap = res;
|
||||||
else if(INVERSE) currentmap = gp::new_inverse();
|
|
||||||
else if(fake::in()) currentmap = fake::new_map();
|
|
||||||
else if(asonov::in()) currentmap = asonov::new_map();
|
else if(asonov::in()) currentmap = asonov::new_map();
|
||||||
else if(nonisotropic || hybri) currentmap = nisot::new_map();
|
else if(nonisotropic || hybri) currentmap = nisot::new_map();
|
||||||
|
else if(INVERSE) currentmap = gp::new_inverse();
|
||||||
|
else if(fake::in()) currentmap = fake::new_map();
|
||||||
#if CAP_CRYSTAL
|
#if CAP_CRYSTAL
|
||||||
else if(cryst) currentmap = crystal::new_map();
|
else if(cryst) currentmap = crystal::new_map();
|
||||||
#endif
|
#endif
|
||||||
@ -405,7 +408,7 @@ EX void clearfrom(heptagon *at) {
|
|||||||
}
|
}
|
||||||
int edges = at->degree();
|
int edges = at->degree();
|
||||||
if(bt::in() && WDIM == 2) edges = at->c7->type;
|
if(bt::in() && WDIM == 2) edges = at->c7->type;
|
||||||
for(int i=0; i<edges; i++) if(at->move(i)) {
|
for(int i=0; i<edges; i++) if(at->move(i) && at->move(i) != at) {
|
||||||
if(at->move(i)->alt != &deletion_marker)
|
if(at->move(i)->alt != &deletion_marker)
|
||||||
q.push(at->move(i));
|
q.push(at->move(i));
|
||||||
unlink_cdata(at->move(i));
|
unlink_cdata(at->move(i));
|
||||||
@ -554,7 +557,9 @@ EX int celldistAlt(cell *c) {
|
|||||||
|
|
||||||
/** direction upwards in the tree */
|
/** direction upwards in the tree */
|
||||||
EX int updir(heptagon *h) {
|
EX int updir(heptagon *h) {
|
||||||
|
#if CAP_BT
|
||||||
if(bt::in()) return bt::updir();
|
if(bt::in()) return bt::updir();
|
||||||
|
#endif
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
if(WDIM == 3 && reg3::in_rule()) {
|
if(WDIM == 3 && reg3::in_rule()) {
|
||||||
for(int i=0; i<S7; i++) if(h->move(i) && h->move(i)->distance < h->distance)
|
for(int i=0; i<S7; i++) if(h->move(i) && h->move(i)->distance < h->distance)
|
||||||
@ -815,10 +820,12 @@ cdata *getHeptagonCdata(heptagon *h) {
|
|||||||
if(sphere || quotient) h = currentmap->gamestart()->master;
|
if(sphere || quotient) h = currentmap->gamestart()->master;
|
||||||
|
|
||||||
bool starting = h->s == hsOrigin;
|
bool starting = h->s == hsOrigin;
|
||||||
|
#if CAP_BT
|
||||||
if(bt::in()) {
|
if(bt::in()) {
|
||||||
if(bt::mapside(h) == 0) starting = true;
|
if(bt::mapside(h) == 0) starting = true;
|
||||||
for(int i=0; i<h->type; i++) if(bt::mapside(h->cmove(i)) == 0) starting = true;
|
for(int i=0; i<h->type; i++) if(bt::mapside(h->cmove(i)) == 0) starting = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(starting) {
|
if(starting) {
|
||||||
h->cdata = new cdata(orig_cdata);
|
h->cdata = new cdata(orig_cdata);
|
||||||
@ -866,7 +873,12 @@ cdata *getHeptagonCdata(heptagon *h) {
|
|||||||
cdata *getEuclidCdata(gp::loc h) {
|
cdata *getEuclidCdata(gp::loc h) {
|
||||||
|
|
||||||
int x = h.first, y = h.second;
|
int x = h.first, y = h.second;
|
||||||
|
|
||||||
|
#if CAP_ARCM
|
||||||
auto& data = arcm::in() ? arcm::get_cdata() : euc::get_cdata();
|
auto& data = arcm::in() ? arcm::get_cdata() : euc::get_cdata();
|
||||||
|
#else
|
||||||
|
auto& data = euc::get_cdata();
|
||||||
|
#endif
|
||||||
|
|
||||||
// hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
|
// hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
|
||||||
if(data.count(h)) return &(data[h]);
|
if(data.count(h)) return &(data[h]);
|
||||||
@ -918,6 +930,7 @@ int ld_to_int(ld x) {
|
|||||||
return int(x + 1000000.5) - 1000000;
|
return int(x + 1000000.5) - 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CAP_ARCM
|
||||||
EX gp::loc pseudocoords(cell *c) {
|
EX gp::loc pseudocoords(cell *c) {
|
||||||
transmatrix T = arcm::archimedean_gmatrix[c->master].second;
|
transmatrix T = arcm::archimedean_gmatrix[c->master].second;
|
||||||
return {ld_to_int(T[0][LDIM]), ld_to_int((spin(60*degree) * T)[0][LDIM])};
|
return {ld_to_int(T[0][LDIM]), ld_to_int((spin(60*degree) * T)[0][LDIM])};
|
||||||
@ -935,19 +948,22 @@ EX cdata *arcmCdata(cell *c) {
|
|||||||
dynamicval<hrmap*> cm(currentmap, arcm::current_altmap);
|
dynamicval<hrmap*> cm(currentmap, arcm::current_altmap);
|
||||||
return getHeptagonCdata(h2);
|
return getHeptagonCdata(h2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
EX int getCdata(cell *c, int j) {
|
EX int getCdata(cell *c, int j) {
|
||||||
if(fake::in()) return FPIU(getCdata(c, j));
|
if(fake::in()) return FPIU(getCdata(c, j));
|
||||||
if(INVERSE) {
|
if(hybri) { c = hybrid::get_where(c).first; return PIU(getBits(c)); }
|
||||||
|
else if(INVERSE) {
|
||||||
cell *c1 = gp::get_mapped(c);
|
cell *c1 = gp::get_mapped(c);
|
||||||
return UIU(getCdata(c1, j));
|
return UIU(getCdata(c1, j));
|
||||||
}
|
}
|
||||||
if(hybri) { c = hybrid::get_where(c).first; return PIU(getBits(c)); }
|
|
||||||
else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->val[j];
|
else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->val[j];
|
||||||
|
#if CAP_ARCM
|
||||||
else if(arcm::in() && euclid)
|
else if(arcm::in() && euclid)
|
||||||
return getEuclidCdata(pseudocoords(c))->val[j];
|
return getEuclidCdata(pseudocoords(c))->val[j];
|
||||||
else if(arcm::in() && hyperbolic)
|
else if(arcm::in() && hyperbolic)
|
||||||
return arcmCdata(c)->val[j]*3;
|
return arcmCdata(c)->val[j]*3;
|
||||||
|
#endif
|
||||||
else if(!geometry_supports_cdata()) return 0;
|
else if(!geometry_supports_cdata()) return 0;
|
||||||
else if(ctof(c)) return getHeptagonCdata(c->master)->val[j]*3;
|
else if(ctof(c)) return getHeptagonCdata(c->master)->val[j]*3;
|
||||||
else {
|
else {
|
||||||
@ -961,16 +977,18 @@ EX int getCdata(cell *c, int j) {
|
|||||||
|
|
||||||
EX int getBits(cell *c) {
|
EX int getBits(cell *c) {
|
||||||
if(fake::in()) return FPIU(getBits(c));
|
if(fake::in()) return FPIU(getBits(c));
|
||||||
if(INVERSE) {
|
if(hybri) { c = hybrid::get_where(c).first; return PIU(getBits(c)); }
|
||||||
|
else if(INVERSE) {
|
||||||
cell *c1 = gp::get_mapped(c);
|
cell *c1 = gp::get_mapped(c);
|
||||||
return UIU(getBits(c1));
|
return UIU(getBits(c1));
|
||||||
}
|
}
|
||||||
if(hybri) { c = hybrid::get_where(c).first; return PIU(getBits(c)); }
|
|
||||||
else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->bits;
|
else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->bits;
|
||||||
else if(arcm::in() && euclid)
|
#if CAP_ARCM
|
||||||
|
else if(arcm::in() && euclid)
|
||||||
return getEuclidCdata(pseudocoords(c))->bits;
|
return getEuclidCdata(pseudocoords(c))->bits;
|
||||||
else if(arcm::in() && (hyperbolic || sl2))
|
else if(arcm::in() && (hyperbolic || sl2))
|
||||||
return arcmCdata(c)->bits;
|
return arcmCdata(c)->bits;
|
||||||
|
#endif
|
||||||
else if(!geometry_supports_cdata()) return 0;
|
else if(!geometry_supports_cdata()) return 0;
|
||||||
else if(c == c->master->c7) return getHeptagonCdata(c->master)->bits;
|
else if(c == c->master->c7) return getHeptagonCdata(c->master)->bits;
|
||||||
else {
|
else {
|
||||||
@ -1108,7 +1126,7 @@ EX int celldistance(cell *c1, cell *c2) {
|
|||||||
if(hybri) return hybrid::celldistance(c1, c2);
|
if(hybri) return hybrid::celldistance(c1, c2);
|
||||||
|
|
||||||
#if CAP_FIELD
|
#if CAP_FIELD
|
||||||
if(geometry == gFieldQuotient) {
|
if(geometry == gFieldQuotient && (PURE || BITRUNCATED)) {
|
||||||
int d = fieldpattern::field_celldistance(c1, c2);
|
int d = fieldpattern::field_celldistance(c1, c2);
|
||||||
if(d != DISTANCE_UNKNOWN) return d;
|
if(d != DISTANCE_UNKNOWN) return d;
|
||||||
}
|
}
|
||||||
|
@ -534,11 +534,13 @@ void celldrawer::setcolors() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case waMineUnknown: case waMineMine:
|
case waMineUnknown: case waMineMine:
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(mine::marked_safe(c))
|
if(mine::marked_safe(c))
|
||||||
fcol = wcol = gradient(wcol, 0x40FF40, 0, 0.2, 1);
|
fcol = wcol = gradient(wcol, 0x40FF40, 0, 0.2, 1);
|
||||||
else if(mine::marked_mine(c))
|
else if(mine::marked_mine(c))
|
||||||
fcol = wcol = gradient(wcol, 0xFF4040, -1, sintick(100), 1);
|
fcol = wcol = gradient(wcol, 0xFF4040, -1, sintick(100), 1);
|
||||||
// fallthrough
|
// fallthrough
|
||||||
|
#endif
|
||||||
|
|
||||||
case waMineOpen:
|
case waMineOpen:
|
||||||
if(wmblack || wmascii) {
|
if(wmblack || wmascii) {
|
||||||
@ -1352,7 +1354,9 @@ void celldrawer::draw_features() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case waTerraWarrior:
|
case waTerraWarrior:
|
||||||
|
#if CAP_COMPLEX2
|
||||||
drawTerraWarrior(V, terracotta::randterra ? (c->landparam & 7) : (5 - (c->landparam & 7)), 7, 0);
|
drawTerraWarrior(V, terracotta::randterra ? (c->landparam & 7) : (5 - (c->landparam & 7)), 7, 0);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case waBoat: case waStrandedBoat:
|
case waBoat: case waStrandedBoat:
|
||||||
|
@ -4139,3 +4139,33 @@ graphics/UI bugfixes:
|
|||||||
- fixed the issues with Orb of Yendor
|
- fixed the issues with Orb of Yendor
|
||||||
- fixed a bug in S2xE, and choosing cells in sphere
|
- fixed a bug in S2xE, and choosing cells in sphere
|
||||||
- fixed Friendly Ghosts
|
- fixed Friendly Ghosts
|
||||||
|
|
||||||
|
2020-11-02 00:08 Update 11.4:
|
||||||
|
|
||||||
|
* Panini perspective projection (allows wider vision -- configurable in 3d config -> FOV)
|
||||||
|
* Changed the default texture_step to 4
|
||||||
|
* An option to hide the flat projection in hyperboloid
|
||||||
|
* improved plain floor shapes in arbitrary tessellations
|
||||||
|
* fixed the Asonov cat geometry
|
||||||
|
* Five new projections: Poor Man (hyperbolic only), Panini, retroazimuthal: Craig, Hammer, Littrow (retro-Hammer buggy on sphere)
|
||||||
|
* Various fixes related to product spaces, especially product+inverse
|
||||||
|
* Fixed the navigation keys in dialogs
|
||||||
|
* fixed duals for Euclidean tessellations
|
||||||
|
|
||||||
|
Also, improvements in the Web version -- Backspace not Esc to exit dialogs, auto-resizing, raytracer is available.
|
||||||
|
Not yet in HyperRogue online, but see: https://zenorogue.itch.io/bringris
|
||||||
|
|
||||||
|
2020-11-05 18:53 Update 11.4a:
|
||||||
|
|
||||||
|
- fixed the aura when camera angle changed
|
||||||
|
- fixed selecting large regions for copying with mouse
|
||||||
|
- messages at 30 treasures etc. should no longer appear in PTM
|
||||||
|
- fixed a bug which allowed changing the generation/game range outside of cheat mode
|
||||||
|
- fixed drawing of creatures in kill list (visible e.g. for dogs)
|
||||||
|
- the RGB/RGBA hex value color is now shown with leading 0s
|
||||||
|
- Orb of the Mind now actually kills reptiles
|
||||||
|
- Orb of Chaos is now forbidden in the Princess Quest
|
||||||
|
- highlight mode setting should be saved now
|
||||||
|
- improved the safe move checking (fixes some minor bugs especially in multiplayer)
|
||||||
|
- allies use the new safe move checking now (they now know whether attacking hedgehog warriors/pikemen is safe for them and do it if yes)
|
||||||
|
- golems and bomberbirds now pathfind correctly
|
||||||
|
183
checkmove.cpp
183
checkmove.cpp
@ -39,28 +39,47 @@ EX bool hasSafeOrb(cell *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HDR
|
#if HDR
|
||||||
struct stalemate1 {
|
struct player_move_info {
|
||||||
eMonster who;
|
movei mi;
|
||||||
cell *moveto;
|
|
||||||
cell *pushto;
|
|
||||||
cell *comefrom;
|
|
||||||
cell *swordlast[2], *swordtransit[2], *swordnext[2];
|
cell *swordlast[2], *swordtransit[2], *swordnext[2];
|
||||||
stalemate1(eMonster w, cell *mt, cell *pt, cell *cf) : who(w), moveto(mt), pushto(pt), comefrom(cf) {}
|
player_move_info(movei mi);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EX vector<player_move_info> pmi;
|
||||||
|
EX vector<cell*> pushes;
|
||||||
|
|
||||||
|
player_move_info::player_move_info(movei _mi) : mi(_mi) {
|
||||||
|
for(int b=0; b<2; b++) swordlast[b] = sword::pos(multi::cpid, b);
|
||||||
|
|
||||||
|
dynamicval<sword::sworddir> x7(sword::dir[multi::cpid], sword::shift(mi, sword::dir[multi::cpid]));
|
||||||
|
|
||||||
|
for(int b=0; b<2; b++) {
|
||||||
|
swordnext[b] = sword::pos(multi::cpid, b);
|
||||||
|
swordtransit[b] = NULL;
|
||||||
|
if(swordnext[b] && swordnext[b] != swordlast[b] && !isNeighbor(swordlast[b], swordnext[b])) {
|
||||||
|
forCellEx(c2, swordnext[b])
|
||||||
|
if(c2 != mi.t && c2 != mi.s && isNeighbor(c2, S3==3 ? swordlast[b] : mi.t))
|
||||||
|
swordtransit[b] = c2;
|
||||||
|
if(S3 == 4)
|
||||||
|
forCellEx(c2, mi.s)
|
||||||
|
if(c2 != mi.s && isNeighbor(c2, swordlast[b]))
|
||||||
|
swordtransit[b] = c2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EX bool krakensafe(cell *c) {
|
EX bool krakensafe(cell *c) {
|
||||||
return items[itOrbFish] || items[itOrbAether] ||
|
return items[itOrbFish] || items[itOrbAether] ||
|
||||||
(c->item == itOrbFish && c->wall == waBoat) ||
|
(c->item == itOrbFish && c->wall == waBoat) ||
|
||||||
(c->item == itOrbAether && c->wall == waBoat);
|
(c->item == itOrbAether && c->wall == waBoat);
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool monstersnear(stalemate1& sm) {
|
EX bool monstersnear(cell *c, eMonster who) {
|
||||||
|
|
||||||
cell *c = sm.moveto;
|
|
||||||
bool eaten = false;
|
bool eaten = false;
|
||||||
|
|
||||||
if(hardcore && sm.who == moPlayer) return false;
|
if(hardcore && who == moPlayer) return false;
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
bool fast = false;
|
bool fast = false;
|
||||||
@ -76,9 +95,9 @@ EX bool monstersnear(stalemate1& sm) {
|
|||||||
who_kills_me = moCrusher; res++;
|
who_kills_me = moCrusher; res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sm.who == moPlayer || items[itOrbEmpathy]) {
|
if(who == moPlayer || items[itOrbEmpathy]) {
|
||||||
fast = (items[itOrbSpeed] && (items[itOrbSpeed] & 1));
|
fast = (items[itOrbSpeed] && (items[itOrbSpeed] & 1));
|
||||||
if(sm.who == moPlayer && sm.moveto->item == itOrbSpeed && !items[itOrbSpeed]) fast = true;
|
if(who == moPlayer && c->item == itOrbSpeed && !items[itOrbSpeed]) fast = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(havewhat&HF_OUTLAW) {
|
if(havewhat&HF_OUTLAW) {
|
||||||
@ -103,7 +122,7 @@ EX bool monstersnear(stalemate1& sm) {
|
|||||||
if(!logical_adjacent(c3, c3->monst, c2) || !logical_adjacent(c2, c3->monst, c) || (c3->monst == moWitchSpeed && c2->land != laPower))
|
if(!logical_adjacent(c3, c3->monst, c2) || !logical_adjacent(c2, c3->monst, c) || (c3->monst == moWitchSpeed && c2->land != laPower))
|
||||||
continue;
|
continue;
|
||||||
if(elec::affected(c3)) continue;
|
if(elec::affected(c3)) continue;
|
||||||
if(c3->stuntime > (sm.who == moPlayer ? 0 : 1)) continue;
|
if(c3->stuntime > (who == moPlayer ? 0 : 1)) continue;
|
||||||
// speedwitches can only attack not-fastened monsters,
|
// speedwitches can only attack not-fastened monsters,
|
||||||
// others can only attack if the move is not fastened
|
// others can only attack if the move is not fastened
|
||||||
if(c3->monst == moWitchSpeed && items[itOrbSpeed]) continue;
|
if(c3->monst == moWitchSpeed && items[itOrbSpeed]) continue;
|
||||||
@ -120,19 +139,19 @@ EX bool monstersnear(stalemate1& sm) {
|
|||||||
|
|
||||||
// consider normal monsters
|
// consider normal monsters
|
||||||
if(c2 &&
|
if(c2 &&
|
||||||
isArmedEnemy(c2, sm.who) &&
|
isArmedEnemy(c2, who) &&
|
||||||
(c2->monst != moLancer || isUnarmed(sm.who) || !logical_adjacent(c, sm.who, c2))) {
|
(c2->monst != moLancer || isUnarmed(who) || !logical_adjacent(c, who, c2))) {
|
||||||
eMonster m = c2->monst;
|
eMonster m = c2->monst;
|
||||||
if(elec::affected(c2)) continue;
|
if(elec::affected(c2)) continue;
|
||||||
if(fast && c2->monst != moWitchSpeed) continue;
|
if(fast && c2->monst != moWitchSpeed) continue;
|
||||||
// Krakens just destroy boats
|
// Krakens just destroy boats
|
||||||
if(c2->monst == moKrakenT && onboat(sm)) {
|
if(c2->monst == moKrakenT && c->wall == waBoat) {
|
||||||
if(krakensafe(c)) continue;
|
if(krakensafe(c)) continue;
|
||||||
else if(warningprotection(XLAT("This move appears dangerous -- are you sure?")) && res == 0) m = moWarning;
|
else if(warningprotection(XLAT("This move appears dangerous -- are you sure?")) && res == 0) m = moWarning;
|
||||||
else continue;
|
else continue;
|
||||||
}
|
}
|
||||||
// they cannot attack through vines
|
// they cannot attack through vines
|
||||||
if(!canAttack(c2, c2->monst, c, sm.who, AF_NEXTTURN)) continue;
|
if(!canAttack(c2, c2->monst, c, who, AF_NEXTTURN)) continue;
|
||||||
if(c2->monst == moWorm || c2->monst == moTentacle || c2->monst == moHexSnake) {
|
if(c2->monst == moWorm || c2->monst == moTentacle || c2->monst == moHexSnake) {
|
||||||
if(passable_for(c2->monst, c, c2, 0))
|
if(passable_for(c2->monst, c, c2, 0))
|
||||||
eaten = true;
|
eaten = true;
|
||||||
@ -142,18 +161,16 @@ EX bool monstersnear(stalemate1& sm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sm.who == moPlayer && res && (markOrb2(itOrbShield) || markOrb2(itOrbShell)) && !eaten)
|
if(who == moPlayer && res && (markOrb2(itOrbShield) || markOrb2(itOrbShell)) && !eaten)
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
if(sm.who == moPlayer && res && markOrb2(itOrbDomination) && c->monst)
|
if(who == moPlayer && res && markOrb2(itOrbDomination) && c->monst)
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
return !!res;
|
return !!res;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool monstersnear2();
|
EX bool monstersnear_aux() {
|
||||||
|
|
||||||
EX bool monstersnear2() {
|
|
||||||
changes.value_set(passive_switch, (gold() & 1) ? moSwitch1 : moSwitch2);
|
changes.value_set(passive_switch, (gold() & 1) ? moSwitch1 : moSwitch2);
|
||||||
multi::cpid++;
|
multi::cpid++;
|
||||||
bool b = false;
|
bool b = false;
|
||||||
@ -162,22 +179,33 @@ EX bool monstersnear2() {
|
|||||||
if(multi::cpid == multi::players || multi::players == 1 || multi::checkonly) {
|
if(multi::cpid == multi::players || multi::players == 1 || multi::checkonly) {
|
||||||
|
|
||||||
if(shmup::delayed_safety) return false;
|
if(shmup::delayed_safety) return false;
|
||||||
dynamicval<eMonster> sw(passive_switch, passive_switch);
|
|
||||||
|
for(int i=0; i<isize(pmi); i++)
|
||||||
for(int i=0; i<isize(stalemate::moves); i++)
|
for(int j=0; j<isize(pmi); j++) if(i != j) {
|
||||||
for(int j=0; j<isize(stalemate::moves); j++) if(i != j) {
|
if(swordConflict(pmi[i], pmi[j])) {
|
||||||
if(swordConflict(stalemate::moves[i], stalemate::moves[j])) {
|
|
||||||
b = true;
|
b = true;
|
||||||
who_kills_me = moEnergySword;
|
who_kills_me = moEnergySword;
|
||||||
}
|
}
|
||||||
if(multi::player[i].at == multi::player[j].at)
|
if(pmi[i].mi.t == pmi[j].mi.t)
|
||||||
{ b = true; who_kills_me = moFireball; }
|
{ b = true; who_kills_me = moFireball; }
|
||||||
if(celldistance(multi::player[i].at, multi::player[j].at) > 8)
|
if(celldistance(pmi[i].mi.t, pmi[j].mi.t) > 8)
|
||||||
{ b = true; who_kills_me = moAirball; }
|
{ b = true; who_kills_me = moAirball; }
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; !b && i<isize(stalemate::moves); i++)
|
for(auto& pushto: pushes)
|
||||||
b = monstersnear(stalemate::moves[i]);
|
for(auto& mi: pmi)
|
||||||
|
if(pushto == mi.mi.t) {
|
||||||
|
b = true; who_kills_me = moTongue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<isize(pushes); i++)
|
||||||
|
for(int j=0; j<i; j++)
|
||||||
|
if(pushes[i] == pushes[j]) {
|
||||||
|
b = true; who_kills_me = moCrushball;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; !b && i<isize(pmi); i++)
|
||||||
|
b = monstersnear(pmi[i].mi.t, moPlayer);
|
||||||
}
|
}
|
||||||
else b = !multimove();
|
else b = !multimove();
|
||||||
multi::cpid--;
|
multi::cpid--;
|
||||||
@ -185,94 +213,17 @@ EX bool monstersnear2() {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool monstersnear(cell *c, eMonster who, cell *pushto, cell *comefrom) {
|
/** like monstersnear but add the potential moves of other players into account */
|
||||||
|
EX bool monstersnear_add_pmi(player_move_info pmi0) {
|
||||||
if(peace::on) return 0; // you are safe
|
pmi.push_back(pmi0);
|
||||||
|
bool b = monstersnear_aux();
|
||||||
stalemate1 sm(who, c, pushto, comefrom);
|
pmi.pop_back();
|
||||||
|
|
||||||
if(who == moPlayer) for(int b=0; b<2; b++) sm.swordlast[b] = sword::pos(multi::cpid, b);
|
|
||||||
|
|
||||||
cell *none = NULL;
|
|
||||||
cell **wcw = &cwt.at;
|
|
||||||
if(who != moPlayer) wcw = &none;
|
|
||||||
else if(multi::players > 1) wcw = &multi::player[multi::cpid].at;
|
|
||||||
|
|
||||||
dynamicval<cell*> x5(*wcw, c);
|
|
||||||
dynamicval<bool> x6(stalemate::nextturn, true);
|
|
||||||
dynamicval<sword::sworddir> x7(sword::dir[multi::cpid],
|
|
||||||
who == moPlayer ? sword::shift(comefrom, c, sword::dir[multi::cpid]) :
|
|
||||||
sword::dir[multi::cpid]);
|
|
||||||
|
|
||||||
for(int b=0; b<2; b++) {
|
|
||||||
if(who == moPlayer) {
|
|
||||||
sm.swordnext[b] = sword::pos(multi::cpid, b);
|
|
||||||
sm.swordtransit[b] = NULL;
|
|
||||||
if(sm.swordnext[b] && sm.swordnext[b] != sm.swordlast[b] && !isNeighbor(sm.swordlast[b], sm.swordnext[b])) {
|
|
||||||
forCellEx(c2, sm.swordnext[b])
|
|
||||||
if(c2 != c && c2 != comefrom && isNeighbor(c2, S3==3 ? sm.swordlast[b] : *wcw))
|
|
||||||
sm.swordtransit[b] = c2;
|
|
||||||
if(S3 == 4)
|
|
||||||
forCellEx(c2, c)
|
|
||||||
if(c2 != comefrom && isNeighbor(c2, sm.swordlast[b]))
|
|
||||||
sm.swordtransit[b] = c2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sm.swordnext[b] = sm.swordtransit[b] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stalemate::moves.push_back(sm);
|
|
||||||
|
|
||||||
// dynamicval<eMonster> x7(stalemate::who, who);
|
|
||||||
|
|
||||||
bool b;
|
|
||||||
if(who == moPlayer && c->wall == waBigStatue) {
|
|
||||||
eWall w = comefrom->wall;
|
|
||||||
c->wall = waNone;
|
|
||||||
if(doesnotFall(comefrom)) comefrom->wall = waBigStatue;
|
|
||||||
b = monstersnear2();
|
|
||||||
comefrom->wall = w;
|
|
||||||
c->wall = waBigStatue;
|
|
||||||
}
|
|
||||||
else if(who == moPlayer && isPushable(c->wall)) {
|
|
||||||
eWall w = c->wall;
|
|
||||||
c->wall = waNone;
|
|
||||||
b = monstersnear2();
|
|
||||||
c->wall = w;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
b = monstersnear2();
|
|
||||||
}
|
|
||||||
stalemate::moves.pop_back();
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX namespace stalemate {
|
|
||||||
EX vector<stalemate1> moves;
|
|
||||||
EX bool nextturn;
|
|
||||||
|
|
||||||
EX bool isMoveto(cell *c) {
|
|
||||||
for(int i=0; i<isize(moves); i++) if(moves[i].moveto == c) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EX bool isPushto(cell *c) {
|
|
||||||
for(int i=0; i<isize(moves); i++) if(moves[i].pushto == c) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
EX }
|
|
||||||
|
|
||||||
EX bool onboat(stalemate1& sm) {
|
|
||||||
cell *c = sm.moveto;
|
|
||||||
cell *cf = sm.comefrom;
|
|
||||||
return (c->wall == waBoat) || (cf->wall == waBoat && c->wall == waSea);
|
|
||||||
}
|
|
||||||
|
|
||||||
EX bool multimove() {
|
EX bool multimove() {
|
||||||
if(multi::cpid == 0) lastkills = tkills();
|
if(multi::cpid == 0) lastkills = tkills();
|
||||||
if(!multi::playerActive(multi::cpid)) return !monstersnear2();
|
if(!multi::playerActive(multi::cpid)) return !monstersnear_aux();
|
||||||
cellwalker bcwt = cwt;
|
cellwalker bcwt = cwt;
|
||||||
cwt = multi::player[multi::cpid];
|
cwt = multi::player[multi::cpid];
|
||||||
bool b = movepcto(multi::whereto[multi::cpid]);
|
bool b = movepcto(multi::whereto[multi::cpid]);
|
||||||
@ -293,11 +244,11 @@ EX namespace multi {
|
|||||||
EX bool aftermove;
|
EX bool aftermove;
|
||||||
EX }
|
EX }
|
||||||
|
|
||||||
EX bool swordConflict(const stalemate1& sm1, const stalemate1& sm2) {
|
EX bool swordConflict(const player_move_info& sm1, const player_move_info& sm2) {
|
||||||
if(items[itOrbSword] || items[itOrbSword2])
|
if(items[itOrbSword] || items[itOrbSword2])
|
||||||
for(int b=0; b<2; b++)
|
for(int b=0; b<2; b++)
|
||||||
if(sm1.comefrom == sm2.swordlast[b] || sm1.comefrom == sm2.swordtransit[b] || sm1.comefrom == sm2.swordnext[b])
|
if(sm1.mi.s == sm2.swordlast[b] || sm1.mi.s == sm2.swordtransit[b] || sm1.mi.s == sm2.swordnext[b])
|
||||||
if(sm1.moveto == sm2.swordlast[b] || sm1.moveto == sm2.swordtransit[b] || sm1.moveto == sm2.swordnext[b])
|
if(sm1.mi.t == sm2.swordlast[b] || sm1.mi.t == sm2.swordtransit[b] || sm1.mi.t == sm2.swordnext[b])
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -980,6 +980,8 @@ enum eModel : int {
|
|||||||
// 32..38
|
// 32..38
|
||||||
mdWerner, mdAitoff, mdHammer, mdLoximuthal, mdMiller, mdGallStereographic, mdWinkelTripel,
|
mdWerner, mdAitoff, mdHammer, mdLoximuthal, mdMiller, mdGallStereographic, mdWinkelTripel,
|
||||||
// 39..
|
// 39..
|
||||||
|
mdPoorMan, mdPanini, mdRetroCraig, mdRetroLittrow, mdRetroHammer,
|
||||||
|
// 44..
|
||||||
mdGUARD, mdPixel, mdHyperboloidFlat, mdPolynomial, mdManual
|
mdGUARD, mdPixel, mdHyperboloidFlat, mdPolynomial, mdManual
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -1031,6 +1033,11 @@ EX vector<modelinfo> mdinf = {
|
|||||||
{X3("Miller projection"), mf::euc_boring | mf::band, DEFAULTS}, // scale latitude 4/5 -> Mercator -> 5/4
|
{X3("Miller projection"), mf::euc_boring | mf::band, DEFAULTS}, // scale latitude 4/5 -> Mercator -> 5/4
|
||||||
{X3("Gall stereographic"), mf::euc_boring | mf::band, DEFAULTS}, // like central cylindrical but stereographic
|
{X3("Gall stereographic"), mf::euc_boring | mf::band, DEFAULTS}, // like central cylindrical but stereographic
|
||||||
{X3("Winkel tripel"), mf::euc_boring | mf::broken, DEFAULTS}, // mean of equirec and Aitoff
|
{X3("Winkel tripel"), mf::euc_boring | mf::broken, DEFAULTS}, // mean of equirec and Aitoff
|
||||||
|
{X3("Poor man's square"), mf::euc_boring, DEFAULTS}, //
|
||||||
|
{X3("Panini projection"), mf::euc_boring, DEFAULTS}, //
|
||||||
|
{X3("Craig retroazimuthal"), mf::euc_boring | mf::broken, DEFAULTS}, // retroazimuthal cylindrical
|
||||||
|
{X3("Littrow retroazimuthal"), mf::euc_boring | mf::broken, DEFAULTS}, // retroazimuthal conformal
|
||||||
|
{X3("Hammer retroazimuthal"), mf::euc_boring, DEFAULTS}, // retroazimuthal equidistant
|
||||||
{X3("guard"), 0, DEFAULTS},
|
{X3("guard"), 0, DEFAULTS},
|
||||||
{X3("polynomial"), mf::conformal, DEFAULTS},
|
{X3("polynomial"), mf::conformal, DEFAULTS},
|
||||||
};
|
};
|
||||||
|
19
complex.cpp
19
complex.cpp
@ -2800,12 +2800,18 @@ EX namespace sword {
|
|||||||
EX void determine_sword_angles() {
|
EX void determine_sword_angles() {
|
||||||
sword_angles = 2;
|
sword_angles = 2;
|
||||||
if(SWORDDIM == 3) sword_angles = 1;
|
if(SWORDDIM == 3) sword_angles = 1;
|
||||||
|
#if CAP_IRR
|
||||||
else if(IRREGULAR) sword_angles = 840;
|
else if(IRREGULAR) sword_angles = 840;
|
||||||
|
#endif
|
||||||
|
#if CAP_BT
|
||||||
else if(bt::in()) sword_angles = 42;
|
else if(bt::in()) sword_angles = 42;
|
||||||
|
#endif
|
||||||
|
#if CAP_ARCM
|
||||||
else if(arcm::in()) {
|
else if(arcm::in()) {
|
||||||
if(!PURE) possible_divisor((BITRUNCATED ? 2 : 1) * isize(arcm::current.faces));
|
if(!PURE) possible_divisor((BITRUNCATED ? 2 : 1) * isize(arcm::current.faces));
|
||||||
if(!DUAL) for(int f: arcm::current.faces) possible_divisor(f);
|
if(!DUAL) for(int f: arcm::current.faces) possible_divisor(f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
possible_divisor(S7);
|
possible_divisor(S7);
|
||||||
if(BITRUNCATED) possible_divisor(S3);
|
if(BITRUNCATED) possible_divisor(S3);
|
||||||
@ -2861,10 +2867,13 @@ EX namespace sword {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// from c1 to c2
|
// from c1 to c2
|
||||||
EX sworddir shift(cell *c1, cell *c2, sworddir d) {
|
EX sworddir shift(movei mi, sworddir d) {
|
||||||
if(!c1 || !c2) return d;
|
cell *c1 = mi.s;
|
||||||
int s1 = neighborId(c1, c2);
|
cell *c2 = mi.t;
|
||||||
int s2 = neighborId(c2, c1);
|
if(!mi.proper()) return d;
|
||||||
|
int s1 = mi.d;
|
||||||
|
int s2 = mi.rev_dir();
|
||||||
|
neighborId(c2, c1);
|
||||||
if(s1 < 0 || s2 < 0) return d;
|
if(s1 < 0 || s2 < 0) return d;
|
||||||
if(SWORDDIM == 2) {
|
if(SWORDDIM == 2) {
|
||||||
int sub = (hybri) ? 2 : 0;
|
int sub = (hybri) ? 2 : 0;
|
||||||
@ -3347,7 +3356,7 @@ EX namespace ca {
|
|||||||
|
|
||||||
EX eWall wlive = waFloorA;
|
EX eWall wlive = waFloorA;
|
||||||
|
|
||||||
EX unordered_set<cell*> changed;
|
EX set<cell*> changed;
|
||||||
|
|
||||||
EX void list_adj(cell *c) {
|
EX void list_adj(cell *c) {
|
||||||
changed.insert(c);
|
changed.insert(c);
|
||||||
|
5536
config.cpp
5536
config.cpp
File diff suppressed because it is too large
Load Diff
@ -480,11 +480,13 @@ EX void handleKeyNormal(int sym, int uni) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(DEFAULTNOR(sym)) {
|
if(DEFAULTNOR(sym)) {
|
||||||
gmodekeys(sym, uni);
|
gmodekeys(sym, uni);
|
||||||
if(uni == 'm' && canmove && (centerover == cwt.at ? mouseover : centerover))
|
if(uni == 'm' && canmove && (centerover == cwt.at ? mouseover : centerover))
|
||||||
mine::performMarkCommand(mouseover);
|
mine::performMarkCommand(mouseover);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(DEFAULTCONTROL) {
|
if(DEFAULTCONTROL) {
|
||||||
if(sym == '.' || sym == 's') movepcto(-1, 1);
|
if(sym == '.' || sym == 's') movepcto(-1, 1);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
EX namespace crystal {
|
EX namespace crystal {
|
||||||
#if CAP_CRYSTAL
|
|
||||||
|
|
||||||
#if HDR
|
#if HDR
|
||||||
static const int MAXDIM = 7;
|
static const int MAXDIM = 7;
|
||||||
@ -34,6 +33,8 @@ struct ldcoord : public array<ld, MAXDIM> {
|
|||||||
static const ldcoord ldc0 = {};
|
static const ldcoord ldc0 = {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CAP_CRYSTAL
|
||||||
|
|
||||||
/** Crystal can be bitruncated either by changing variation to bitruncated.
|
/** Crystal can be bitruncated either by changing variation to bitruncated.
|
||||||
* In case of the 4D Crystal, the standard HyperRogue bitruncation becomes
|
* In case of the 4D Crystal, the standard HyperRogue bitruncation becomes
|
||||||
* confused by having both the original and new vertices of degree 8.
|
* confused by having both the original and new vertices of degree 8.
|
||||||
@ -470,7 +471,7 @@ struct hrmap_crystal : hrmap_standard {
|
|||||||
map<coord, heptagon*> heptagon_at;
|
map<coord, heptagon*> heptagon_at;
|
||||||
map<int, eLand> landmemo;
|
map<int, eLand> landmemo;
|
||||||
map<coord, eLand> landmemo4;
|
map<coord, eLand> landmemo4;
|
||||||
unordered_map<cell*, unordered_map<cell*, int>> distmemo;
|
map<cell*, map<cell*, int>> distmemo;
|
||||||
map<cell*, ldcoord> sgc;
|
map<cell*, ldcoord> sgc;
|
||||||
cell *camelot_center;
|
cell *camelot_center;
|
||||||
ldcoord camelot_coord;
|
ldcoord camelot_coord;
|
||||||
|
@ -721,12 +721,14 @@ int read_cheat_args() {
|
|||||||
inv::compute();
|
inv::compute();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if CAP_COMPLEX2
|
||||||
else if(argis("-ambush")) {
|
else if(argis("-ambush")) {
|
||||||
// make all ambushes use the given number of dogs
|
// make all ambushes use the given number of dogs
|
||||||
// example: hyper -W Hunt -IP Shield 1 -ambush 60
|
// example: hyper -W Hunt -IP Shield 1 -ambush 60
|
||||||
PHASE(3) cheat();
|
PHASE(3) cheat();
|
||||||
shift(); ambush::fixed_size = argi();
|
shift(); ambush::fixed_size = argi();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if(argis("-testdistances")) {
|
else if(argis("-testdistances")) {
|
||||||
PHASE(3); shift(); test_distances(argi());
|
PHASE(3); shift(); test_distances(argi());
|
||||||
}
|
}
|
||||||
@ -875,6 +877,11 @@ int read_cheat_args() {
|
|||||||
cheat();
|
cheat();
|
||||||
gen_wandering = false;
|
gen_wandering = false;
|
||||||
}
|
}
|
||||||
|
else if(argis("-hroll")) {
|
||||||
|
shift();
|
||||||
|
int i = argi();
|
||||||
|
while(i>0) i--, hrand(10);
|
||||||
|
}
|
||||||
else if(argis("-W")) {
|
else if(argis("-W")) {
|
||||||
PHASEFROM(2);
|
PHASEFROM(2);
|
||||||
shift();
|
shift();
|
||||||
|
41
dialogs.cpp
41
dialogs.cpp
@ -64,7 +64,10 @@ EX namespace dialog {
|
|||||||
EX color_t dialogcolor = 0xC0C0C0;
|
EX color_t dialogcolor = 0xC0C0C0;
|
||||||
|
|
||||||
EX void addBack() {
|
EX void addBack() {
|
||||||
addItem(XLAT("go back"), ISWEB ? SDLK_BACKSPACE : SDLK_ESCAPE);
|
addItem(XLAT("go back"),
|
||||||
|
(cmode & sm::NUMBER) ? SDLK_RETURN :
|
||||||
|
ISWEB ? SDLK_BACKSPACE :
|
||||||
|
SDLK_ESCAPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void addHelp() {
|
EX void addHelp() {
|
||||||
@ -522,21 +525,38 @@ EX namespace dialog {
|
|||||||
bool isitem(item& it) {
|
bool isitem(item& it) {
|
||||||
return it.type == diItem || it.type == diBigItem;
|
return it.type == diItem || it.type == diBigItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX void handle_actions(int &sym, int &uni) {
|
||||||
|
if(key_actions.count(uni)) {
|
||||||
|
key_actions[uni]();
|
||||||
|
sym = uni = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(key_actions.count(sym)) {
|
||||||
|
key_actions[sym]();
|
||||||
|
sym = uni = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EX void handleNavigation(int &sym, int &uni) {
|
EX void handleNavigation(int &sym, int &uni) {
|
||||||
if(uni == '\n' || uni == '\r' || DIRECTIONKEY == SDLK_KP5)
|
if(uni == '\n' || uni == '\r' || DIRECTIONKEY == SDLK_KP5) {
|
||||||
for(int i=0; i<isize(items); i++)
|
for(int i=0; i<isize(items); i++)
|
||||||
if(isitem(items[i]))
|
if(isitem(items[i]))
|
||||||
if(items[i].body == highlight_text) {
|
if(items[i].body == highlight_text) {
|
||||||
uni = sym = items[i].key;
|
uni = sym = items[i].key;
|
||||||
|
handle_actions(sym, uni);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(DKEY == SDLK_PAGEDOWN) {
|
if(DKEY == SDLK_PAGEDOWN) {
|
||||||
|
uni = sym = 0;
|
||||||
for(int i=0; i<isize(items); i++)
|
for(int i=0; i<isize(items); i++)
|
||||||
if(isitem(items[i]))
|
if(isitem(items[i]))
|
||||||
highlight_text = items[i].body;
|
highlight_text = items[i].body;
|
||||||
}
|
}
|
||||||
if(DKEY == SDLK_PAGEUP) {
|
if(DKEY == SDLK_PAGEUP) {
|
||||||
|
uni = sym = 0;
|
||||||
for(int i=0; i<isize(items); i++)
|
for(int i=0; i<isize(items); i++)
|
||||||
if(isitem(items[i])) {
|
if(isitem(items[i])) {
|
||||||
highlight_text = items[i].body;
|
highlight_text = items[i].body;
|
||||||
@ -544,11 +564,11 @@ EX namespace dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(DKEY == SDLK_UP) {
|
if(DKEY == SDLK_UP) {
|
||||||
|
uni = sym = 0;
|
||||||
string last = "";
|
string last = "";
|
||||||
for(int i=0; i<isize(items); i++)
|
for(int i=0; i<isize(items); i++)
|
||||||
if(isitem(items[i]))
|
if(isitem(items[i]))
|
||||||
last = items[i].body;
|
last = items[i].body;
|
||||||
uni = sym = 0;
|
|
||||||
for(int i=0; i<isize(items); i++)
|
for(int i=0; i<isize(items); i++)
|
||||||
if(isitem(items[i])) {
|
if(isitem(items[i])) {
|
||||||
if(items[i].body == highlight_text) {
|
if(items[i].body == highlight_text) {
|
||||||
@ -559,6 +579,7 @@ EX namespace dialog {
|
|||||||
highlight_text = last;
|
highlight_text = last;
|
||||||
}
|
}
|
||||||
if(DKEY == SDLK_DOWN) {
|
if(DKEY == SDLK_DOWN) {
|
||||||
|
uni = sym = 0;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
for(int i=0; i<isize(items); i++)
|
for(int i=0; i<isize(items); i++)
|
||||||
if(isitem(items[i])) {
|
if(isitem(items[i])) {
|
||||||
@ -570,18 +591,8 @@ EX namespace dialog {
|
|||||||
highlight_text = items[i].body;
|
highlight_text = items[i].body;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uni = sym = 0;
|
|
||||||
}
|
|
||||||
if(key_actions.count(uni)) {
|
|
||||||
key_actions[uni]();
|
|
||||||
sym = uni = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(key_actions.count(sym)) {
|
|
||||||
key_actions[sym]();
|
|
||||||
sym = uni = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
handle_actions(sym, uni);
|
||||||
}
|
}
|
||||||
|
|
||||||
color_t colorhistory[10] = {
|
color_t colorhistory[10] = {
|
||||||
@ -697,7 +708,7 @@ EX namespace dialog {
|
|||||||
getcstat = 'A' + i, inslider = true;
|
getcstat = 'A' + i, inslider = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + itsh(color), ' ', 8, 0, color >> (colorAlpha ? ash : 0));
|
displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + format(colorAlpha ? "%08X" : "%06X", color), ' ', 8, 0, color >> (colorAlpha ? ash : 0));
|
||||||
|
|
||||||
if(extra_options) extra_options();
|
if(extra_options) extra_options();
|
||||||
|
|
||||||
|
@ -93,9 +93,11 @@ void launch(int seed, int elimit, int hlimit) {
|
|||||||
cl1 = cl.lst;
|
cl1 = cl.lst;
|
||||||
for(cell *c: cl.lst) {
|
for(cell *c: cl.lst) {
|
||||||
c->wall = waNone, c->land = laCanvas;
|
c->wall = waNone, c->land = laCanvas;
|
||||||
|
#if CAP_ARCM
|
||||||
int id = arcm::current.tilegroup[arcm::id_of(c->master)];
|
int id = arcm::current.tilegroup[arcm::id_of(c->master)];
|
||||||
color_t yellows[5] = { 0x80C080, 0x80C0C0, 0x8080C0, 0xC080C0, 0xC0C080 };
|
color_t yellows[5] = { 0x80C080, 0x80C0C0, 0x8080C0, 0xC080C0, 0xC0C080 };
|
||||||
c->landparam = yellows[id];
|
c->landparam = yellows[id];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
println(hlog, "c1 size = ", isize(cl.lst));
|
println(hlog, "c1 size = ", isize(cl.lst));
|
||||||
}
|
}
|
||||||
|
12
drawing.cpp
12
drawing.cpp
@ -293,6 +293,8 @@ EX bool two_sided_model() {
|
|||||||
if(pmodel == mdHyperboloid) return !euclid;
|
if(pmodel == mdHyperboloid) return !euclid;
|
||||||
// if(pmodel == mdHemisphere) return true;
|
// if(pmodel == mdHemisphere) return true;
|
||||||
if(pmodel == mdDisk) return sphere;
|
if(pmodel == mdDisk) return sphere;
|
||||||
|
if(pmodel == mdRetroLittrow) return sphere;
|
||||||
|
if(pmodel == mdRetroHammer) return sphere;
|
||||||
if(pmodel == mdHemisphere) return true;
|
if(pmodel == mdHemisphere) return true;
|
||||||
if(pmodel == mdRotatedHyperboles) return true;
|
if(pmodel == mdRotatedHyperboles) return true;
|
||||||
if(pmodel == mdSpiral && pconf.spiral_cone < 360) return true;
|
if(pmodel == mdSpiral && pconf.spiral_cone < 360) return true;
|
||||||
@ -305,6 +307,12 @@ EX int get_side(const hyperpoint& H) {
|
|||||||
double horizon = curnorm / pconf.alpha;
|
double horizon = curnorm / pconf.alpha;
|
||||||
return (H[2] <= -horizon) ? -1 : 1;
|
return (H[2] <= -horizon) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
if(pmodel == mdRetroLittrow && sphere) {
|
||||||
|
return H[2] >= 0 ? 1 : -1;
|
||||||
|
}
|
||||||
|
if(pmodel == mdRetroHammer && sphere) {
|
||||||
|
return H[2] >= 0 ? 1 : -1;
|
||||||
|
}
|
||||||
if(pmodel == mdRotatedHyperboles)
|
if(pmodel == mdRotatedHyperboles)
|
||||||
return H[1] > 0 ? -1 : 1;
|
return H[1] > 0 ? -1 : 1;
|
||||||
if(pmodel == mdHyperboloid && hyperbolic)
|
if(pmodel == mdHyperboloid && hyperbolic)
|
||||||
@ -2111,7 +2119,7 @@ EX void sort_drawqueue() {
|
|||||||
int siz = isize(ptds);
|
int siz = isize(ptds);
|
||||||
|
|
||||||
#if MINIMIZE_GL_CALLS
|
#if MINIMIZE_GL_CALLS
|
||||||
unordered_map<color_t, vector<unique_ptr<drawqueueitem>>> subqueue;
|
map<color_t, vector<unique_ptr<drawqueueitem>>> subqueue;
|
||||||
for(auto& p: ptds) subqueue[(p->prio == PPR::CIRCLE || p->prio == PPR::OUTCIRCLE) ? 0 : p->outline_group()].push_back(move(p));
|
for(auto& p: ptds) subqueue[(p->prio == PPR::CIRCLE || p->prio == PPR::OUTCIRCLE) ? 0 : p->outline_group()].push_back(move(p));
|
||||||
ptds.clear();
|
ptds.clear();
|
||||||
for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r));
|
for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r));
|
||||||
@ -2156,7 +2164,7 @@ EX void reverse_side_priorities() {
|
|||||||
// on the sphere, parts on the back are drawn first
|
// on the sphere, parts on the back are drawn first
|
||||||
EX void draw_backside() {
|
EX void draw_backside() {
|
||||||
DEBBI(DF_GRAPH, ("draw_backside"));
|
DEBBI(DF_GRAPH, ("draw_backside"));
|
||||||
if(pmodel == mdHyperboloid && hyperbolic) {
|
if(pmodel == mdHyperboloid && hyperbolic && pconf.show_hyperboloid_flat) {
|
||||||
dynamicval<eModel> dv (pmodel, mdHyperboloidFlat);
|
dynamicval<eModel> dv (pmodel, mdHyperboloidFlat);
|
||||||
for(auto& ptd: ptds)
|
for(auto& ptd: ptds)
|
||||||
if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
|
if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
|
||||||
|
@ -129,10 +129,11 @@ EX void compute_graphical_distance() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void computePathdist(eMonster param) {
|
EX void computePathdist(eMonster param, bool include_allies IS(true)) {
|
||||||
|
|
||||||
for(cell *c: targets)
|
for(cell *c: targets)
|
||||||
onpath(c, isPlayerOn(c) ? 0 : 1, hrand(c->type));
|
if(include_allies || isPlayerOn(c))
|
||||||
|
onpath(c, isPlayerOn(c) ? 0 : 1, hrand(c->type));
|
||||||
|
|
||||||
int qtarg = isize(targets);
|
int qtarg = isize(targets);
|
||||||
|
|
||||||
@ -157,9 +158,12 @@ EX void computePathdist(eMonster param) {
|
|||||||
int i = (fd+j) % c->type;
|
int i = (fd+j) % c->type;
|
||||||
// printf("i=%d cd=%d\n", i, c->move(i)->cpdist);
|
// printf("i=%d cd=%d\n", i, c->move(i)->cpdist);
|
||||||
cell *c2 = c->move(i);
|
cell *c2 = c->move(i);
|
||||||
|
|
||||||
|
flagtype f = P_MONSTER | P_REVDIR;
|
||||||
|
if(param == moTameBomberbird) f |= P_FLYING;
|
||||||
|
|
||||||
if(c2 && c2->pathdist == PINFD &&
|
if(c2 && c2->pathdist == PINFD &&
|
||||||
passable(c2, (qb<qtarg) && !nonAdjacent(c,c2) && !thruVine(c,c2) ?NULL:c, P_MONSTER | P_REVDIR)) {
|
passable(c2, (qb<qtarg) && !nonAdjacent(c,c2) && !thruVine(c,c2) ?NULL:c, f)) {
|
||||||
|
|
||||||
if(qb >= qtarg) {
|
if(qb >= qtarg) {
|
||||||
if(param == moTortoise && nogoSlow(c, c2)) continue;
|
if(param == moTortoise && nogoSlow(c, c2)) continue;
|
||||||
@ -186,9 +190,9 @@ struct pathdata {
|
|||||||
pathlock--;
|
pathlock--;
|
||||||
clear_pathdata();
|
clear_pathdata();
|
||||||
}
|
}
|
||||||
pathdata(eMonster m) {
|
pathdata(eMonster m, bool include_allies IS(true)) {
|
||||||
checklock();
|
checklock();
|
||||||
computePathdist(m);
|
computePathdist(m, include_allies);
|
||||||
}
|
}
|
||||||
pathdata(int i) {
|
pathdata(int i) {
|
||||||
checklock();
|
checklock();
|
||||||
|
@ -100,7 +100,7 @@ EX namespace euc {
|
|||||||
/** ? */
|
/** ? */
|
||||||
intmatrix inverse_axes;
|
intmatrix inverse_axes;
|
||||||
/** for canonicalization on tori */
|
/** for canonicalization on tori */
|
||||||
unordered_map<coord, int> hash;
|
map<coord, int> hash;
|
||||||
vector<coord> seq;
|
vector<coord> seq;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
@ -150,11 +150,13 @@ EX namespace euc {
|
|||||||
tmatrix[i] = eumove(shifttable[i]);
|
tmatrix[i] = eumove(shifttable[i]);
|
||||||
camelot_center = NULL;
|
camelot_center = NULL;
|
||||||
build_torus3(geometry);
|
build_torus3(geometry);
|
||||||
|
#if CAP_IRR
|
||||||
if(!valid_irr_torus()) {
|
if(!valid_irr_torus()) {
|
||||||
addMessage(XLAT("Error: period mismatch"));
|
addMessage(XLAT("Error: period mismatch"));
|
||||||
eu_input = irr::base_config;
|
eu_input = irr::base_config;
|
||||||
build_torus3(geometry);
|
build_torus3(geometry);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *getOrigin() override {
|
heptagon *getOrigin() override {
|
||||||
@ -168,6 +170,7 @@ EX namespace euc {
|
|||||||
auto h = tailored_alloc<heptagon> (S7);
|
auto h = tailored_alloc<heptagon> (S7);
|
||||||
if(!IRREGULAR)
|
if(!IRREGULAR)
|
||||||
h->c7 = newCell(S7, h);
|
h->c7 = newCell(S7, h);
|
||||||
|
#if CAP_IRR
|
||||||
else {
|
else {
|
||||||
coord m0 = shifttable[0];
|
coord m0 = shifttable[0];
|
||||||
transmatrix dummy;
|
transmatrix dummy;
|
||||||
@ -180,6 +183,7 @@ EX namespace euc {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
h->distance = 0;
|
h->distance = 0;
|
||||||
h->cdata = NULL;
|
h->cdata = NULL;
|
||||||
h->alt = NULL;
|
h->alt = NULL;
|
||||||
@ -534,6 +538,7 @@ EX namespace euc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX bool valid_irr_torus() {
|
EX bool valid_irr_torus() {
|
||||||
|
#if CAP_IRR
|
||||||
if(!IRREGULAR) return true;
|
if(!IRREGULAR) return true;
|
||||||
if(eu.twisted) return false;
|
if(eu.twisted) return false;
|
||||||
for(int i=0; i<2; i++) {
|
for(int i=0; i<2; i++) {
|
||||||
@ -547,6 +552,7 @@ EX namespace euc {
|
|||||||
eu.canonicalize(x0, dm0, dummy, mirr);
|
eu.canonicalize(x0, dm0, dummy, mirr);
|
||||||
if(x0 != euzero || dm0 != eutester) return false;
|
if(x0 != euzero || dm0 != eutester) return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
fake.cpp
10
fake.cpp
@ -81,7 +81,9 @@ EX namespace fake {
|
|||||||
transmatrix S1, S2;
|
transmatrix S1, S2;
|
||||||
ld dist;
|
ld dist;
|
||||||
in_underlying([c, d, &S1, &S2, &dist] {
|
in_underlying([c, d, &S1, &S2, &dist] {
|
||||||
|
#if CAP_ARCM
|
||||||
dynamicval<bool> u(arcm::use_gmatrix, false);
|
dynamicval<bool> u(arcm::use_gmatrix, false);
|
||||||
|
#endif
|
||||||
transmatrix T = currentmap->adj(c, d);
|
transmatrix T = currentmap->adj(c, d);
|
||||||
S1 = rspintox(tC0(T));
|
S1 = rspintox(tC0(T));
|
||||||
transmatrix T1 = spintox(tC0(T)) * T;
|
transmatrix T1 = spintox(tC0(T)) * T;
|
||||||
@ -89,12 +91,16 @@ EX namespace fake {
|
|||||||
S2 = xpush(-dist) * T1;
|
S2 = xpush(-dist) * T1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#if CAP_ARCM
|
||||||
if(arcm::in()) {
|
if(arcm::in()) {
|
||||||
int t = arcm::id_of(c->master);
|
int t = arcm::id_of(c->master);
|
||||||
int t2 = arcm::id_of(c->move(d)->master);
|
int t2 = arcm::id_of(c->move(d)->master);
|
||||||
auto& cof = arcm::current_or_fake();
|
auto& cof = arcm::current_or_fake();
|
||||||
cgi.adjcheck = cof.inradius[t/2] + cof.inradius[t2/2];
|
cgi.adjcheck = cof.inradius[t/2] + cof.inradius[t2/2];
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if(0) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
else if(WDIM == 2) {
|
else if(WDIM == 2) {
|
||||||
|
|
||||||
@ -400,7 +406,9 @@ EX ld around;
|
|||||||
|
|
||||||
/** @brief the value of 'around' which makes the tiling Euclidean */
|
/** @brief the value of 'around' which makes the tiling Euclidean */
|
||||||
EX ld compute_euclidean() {
|
EX ld compute_euclidean() {
|
||||||
|
#if CAP_ARCM
|
||||||
if(arcm::in()) return arcm::current.N * 2 / arcm::current.euclidean_angle_sum;
|
if(arcm::in()) return arcm::current.N * 2 / arcm::current.euclidean_angle_sum;
|
||||||
|
#endif
|
||||||
if(WDIM == 2) return 4 / (S7-2.) + 2;
|
if(WDIM == 2) return 4 / (S7-2.) + 2;
|
||||||
|
|
||||||
if(underlying == gRhombic3) return 3;
|
if(underlying == gRhombic3) return 3;
|
||||||
@ -411,8 +419,10 @@ EX ld compute_euclidean() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX ld around_orig() {
|
EX ld around_orig() {
|
||||||
|
#if CAP_ARCM
|
||||||
if(arcm::in())
|
if(arcm::in())
|
||||||
return arcm::current.N;
|
return arcm::current.N;
|
||||||
|
#endif
|
||||||
if(WDIM == 2)
|
if(WDIM == 2)
|
||||||
return S3;
|
return S3;
|
||||||
if(underlying == gRhombic3)
|
if(underlying == gRhombic3)
|
||||||
|
@ -423,6 +423,48 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
|||||||
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
|
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(arb::in()) {
|
||||||
|
vector<hyperpoint> actual;
|
||||||
|
for(int j=0; j<cor; j++)
|
||||||
|
actual.push_back(get_corner_position(c, j));
|
||||||
|
|
||||||
|
ld min_dist = 1e3;
|
||||||
|
for(int j=0; j<cor; j++)
|
||||||
|
for(int k=0; k<j; k++) {
|
||||||
|
ld dist = hdist(actual[j], actual[k]);
|
||||||
|
if(dist > 1e-6 && dist < min_dist)
|
||||||
|
min_dist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
ld dist = min_dist * (1 - 3 / sca);
|
||||||
|
|
||||||
|
ld area = 0;
|
||||||
|
for(int j=0; j<cor; j++) {
|
||||||
|
hyperpoint current = kleinize(actual[j]);
|
||||||
|
hyperpoint last = kleinize(actual[j?j-1:cor-1]);
|
||||||
|
area += current[0] * last[1] - last[0] * current[1];
|
||||||
|
}
|
||||||
|
if(area < 0) dist = -dist;
|
||||||
|
|
||||||
|
for(int j=0; j<cor; j++) {
|
||||||
|
hyperpoint last = actual[j?j-1:cor-1];
|
||||||
|
hyperpoint current = actual[j];
|
||||||
|
hyperpoint next = actual[j<cor-1?j+1:0];
|
||||||
|
auto T = gpushxto0(current);
|
||||||
|
last = T * last;
|
||||||
|
next = T * next;
|
||||||
|
hyperpoint a = rspintox(last) * ypush0(dist);
|
||||||
|
hyperpoint b = rspintox(last) * xpush(hdist0(last)) * ypush0(dist);
|
||||||
|
|
||||||
|
hyperpoint c = rspintox(next) * ypush0(-dist);
|
||||||
|
hyperpoint d = rspintox(next) * xpush(hdist0(next)) * ypush0(-dist);
|
||||||
|
|
||||||
|
hyperpoint h = linecross(a, b, c, d);
|
||||||
|
|
||||||
|
cornerlist.push_back(rgpushxto0(current) * h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
for(int j=0; j<cor; j++)
|
for(int j=0; j<cor; j++)
|
||||||
@ -771,7 +813,9 @@ void geometry_information::generate_floorshapes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
cell model;
|
static hrmap_standard stdmap;
|
||||||
|
dynamicval<hrmap*> c(currentmap, &stdmap);
|
||||||
|
// cell model;
|
||||||
model.type = S6; generate_floorshapes_for(0, &model, 0, 0);
|
model.type = S6; generate_floorshapes_for(0, &model, 0, 0);
|
||||||
model.type = S7; generate_floorshapes_for(1, &model, bt::in() ? 0 : 1, 0);
|
model.type = S7; generate_floorshapes_for(1, &model, bt::in() ? 0 : 1, 0);
|
||||||
}
|
}
|
||||||
@ -886,24 +930,30 @@ EX int shvid(cell *c) {
|
|||||||
}
|
}
|
||||||
else if(GOLDBERG_INV)
|
else if(GOLDBERG_INV)
|
||||||
return gp::get_plainshape_id(c);
|
return gp::get_plainshape_id(c);
|
||||||
|
#if CAP_IRR
|
||||||
else if(IRREGULAR)
|
else if(IRREGULAR)
|
||||||
return irr::cellindex[c];
|
return irr::cellindex[c];
|
||||||
|
#endif
|
||||||
|
#if CAP_ARCM
|
||||||
else if(arcm::in()) {
|
else if(arcm::in()) {
|
||||||
auto& ac = arcm::current;
|
auto& ac = arcm::current;
|
||||||
int id = arcm::id_of(c->master);
|
int id = arcm::id_of(c->master);
|
||||||
if(ac.regular && id>=2 && id < 2*ac.N) id &= 1;
|
if(ac.regular && id>=2 && id < 2*ac.N) id &= 1;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if(arb::in())
|
else if(arb::in())
|
||||||
return arb::id_of(c->master);
|
return arb::id_of(c->master);
|
||||||
else if(geosupport_football() == 2)
|
else if(geosupport_football() == 2)
|
||||||
return pseudohept(c);
|
return pseudohept(c);
|
||||||
|
#if CAP_BT
|
||||||
else if(geometry == gBinaryTiling)
|
else if(geometry == gBinaryTiling)
|
||||||
return c->type-6;
|
return c->type-6;
|
||||||
else if(kite::in())
|
else if(kite::in())
|
||||||
return kite::getshape(c->master);
|
return kite::getshape(c->master);
|
||||||
else if(geometry == gBinary4 || geometry == gTernary)
|
else if(geometry == gBinary4 || geometry == gTernary)
|
||||||
return c->master->zebraval;
|
return c->master->zebraval;
|
||||||
|
#endif
|
||||||
else if(inforder::mixed()) {
|
else if(inforder::mixed()) {
|
||||||
int t = c->type;
|
int t = c->type;
|
||||||
static vector<bool> computed;
|
static vector<bool> computed;
|
||||||
|
2
game.cpp
2
game.cpp
@ -182,7 +182,7 @@ EX bool activateRecall() {
|
|||||||
|
|
||||||
killFriendlyIvy();
|
killFriendlyIvy();
|
||||||
movecost(cwt.at, recallCell.at, 3);
|
movecost(cwt.at, recallCell.at, 3);
|
||||||
playerMoveEffects(cwt.at, recallCell.at);
|
playerMoveEffects(movei(cwt.at, recallCell.at, TELEPORT));
|
||||||
mirror::destroyAll();
|
mirror::destroyAll();
|
||||||
|
|
||||||
sword::reset();
|
sword::reset();
|
||||||
|
14
geom-exp.cpp
14
geom-exp.cpp
@ -300,6 +300,7 @@ void set_or_configure_geometry(eGeometry g) {
|
|||||||
addMessage(XLAT("Only works with (semi-)regular tilings"));
|
addMessage(XLAT("Only works with (semi-)regular tilings"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if CAP_ARCM
|
||||||
if(arcm::in()) {
|
if(arcm::in()) {
|
||||||
int steps, single_step;
|
int steps, single_step;
|
||||||
if(!arcm::current.get_step_values(steps, single_step)) {
|
if(!arcm::current.get_step_values(steps, single_step)) {
|
||||||
@ -307,6 +308,7 @@ void set_or_configure_geometry(eGeometry g) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dual::may_split_or_do([g] { set_geometry(g); });
|
dual::may_split_or_do([g] { set_geometry(g); });
|
||||||
@ -384,7 +386,9 @@ void ge_select_tiling() {
|
|||||||
|
|
||||||
EX string current_proj_name() {
|
EX string current_proj_name() {
|
||||||
bool h = hyperbolic || sn::in();
|
bool h = hyperbolic || sn::in();
|
||||||
if(vpconf.model != mdDisk)
|
if(vpconf.model == mdPanini && vpconf.alpha == 1)
|
||||||
|
return XLAT("stereographic Panini");
|
||||||
|
else if(vpconf.model != mdDisk)
|
||||||
return models::get_model_name(vpconf.model);
|
return models::get_model_name(vpconf.model);
|
||||||
else if(h && vpconf.alpha == 1)
|
else if(h && vpconf.alpha == 1)
|
||||||
return XLAT("Poincaré model");
|
return XLAT("Poincaré model");
|
||||||
@ -540,8 +544,10 @@ EX void select_quotient_screen() {
|
|||||||
}
|
}
|
||||||
else if(g == gFieldQuotient)
|
else if(g == gFieldQuotient)
|
||||||
pushScreen(showQuotientConfig);
|
pushScreen(showQuotientConfig);
|
||||||
|
#if CAP_CRYSTAL
|
||||||
else if(g == gCrystal)
|
else if(g == gCrystal)
|
||||||
pushScreen(crystal::show);
|
pushScreen(crystal::show);
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
dual::may_split_or_do([g] { set_geometry(g); });
|
dual::may_split_or_do([g] { set_geometry(g); });
|
||||||
start_game();
|
start_game();
|
||||||
@ -707,7 +713,9 @@ EX void showEuclideanMenu() {
|
|||||||
worldsize = euc::eu.det;
|
worldsize = euc::eu.det;
|
||||||
if(BITRUNCATED) worldsize *= (a4 ? 2 : 3);
|
if(BITRUNCATED) worldsize *= (a4 ? 2 : 3);
|
||||||
if(GOLDBERG) worldsize *= cgi.gpdata->area;
|
if(GOLDBERG) worldsize *= cgi.gpdata->area;
|
||||||
|
#if CAP_IRR
|
||||||
if(IRREGULAR) worldsize *= isize(irr::cells) / isize(irr::cells_of_heptagon);
|
if(IRREGULAR) worldsize *= isize(irr::cells) / isize(irr::cells_of_heptagon);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
worldsize = denom ? nom / denom : 0;
|
worldsize = denom ? nom / denom : 0;
|
||||||
@ -794,15 +802,19 @@ EX void showEuclideanMenu() {
|
|||||||
|
|
||||||
dialog::add_action(select_quotient);
|
dialog::add_action(select_quotient);
|
||||||
|
|
||||||
|
#if CAP_ARCM
|
||||||
if(arcm::in()) {
|
if(arcm::in()) {
|
||||||
dialog::addItem(XLAT("advanced parameters"), '4');
|
dialog::addItem(XLAT("advanced parameters"), '4');
|
||||||
dialog::add_action_push(arcm::show);
|
dialog::add_action_push(arcm::show);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CAP_CRYSTAL
|
||||||
if(cryst) {
|
if(cryst) {
|
||||||
dialog::addItem(XLAT("advanced parameters"), '4');
|
dialog::addItem(XLAT("advanced parameters"), '4');
|
||||||
dialog::add_action_push(crystal::show);
|
dialog::add_action_push(crystal::show);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(fake::available()) {
|
if(fake::available()) {
|
||||||
dialog::addItem(XLAT("fake curvature"), '4');
|
dialog::addItem(XLAT("fake curvature"), '4');
|
||||||
|
16
geometry.cpp
16
geometry.cpp
@ -673,12 +673,17 @@ void geometry_information::prepare_basics() {
|
|||||||
plevel = vid.plevel_factor * scalefactor;
|
plevel = vid.plevel_factor * scalefactor;
|
||||||
single_step = 1;
|
single_step = 1;
|
||||||
if(hybri && !prod) {
|
if(hybri && !prod) {
|
||||||
|
#if CAP_ARCM
|
||||||
if(hybrid::underlying == gArchimedean)
|
if(hybrid::underlying == gArchimedean)
|
||||||
arcm::current.get_step_values(psl_steps, single_step);
|
arcm::current.get_step_values(psl_steps, single_step);
|
||||||
|
#else
|
||||||
|
if(0) ;
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
single_step = S3 * S7 - 2 * S7 - 2 * S3;
|
single_step = S3 * S7 - 2 * S7 - 2 * S3;
|
||||||
psl_steps = 2 * S7;
|
psl_steps = 2 * S7;
|
||||||
if(BITRUNCATED) psl_steps *= S3;
|
if(BITRUNCATED) psl_steps *= S3;
|
||||||
|
if(inv) psl_steps = 2 * S3;
|
||||||
if(single_step < 0) single_step = -single_step;
|
if(single_step < 0) single_step = -single_step;
|
||||||
}
|
}
|
||||||
DEBB(DF_GEOM | DF_POLY, ("steps = ", psl_steps, " / ", single_step));
|
DEBB(DF_GEOM | DF_POLY, ("steps = ", psl_steps, " / ", single_step));
|
||||||
@ -913,7 +918,7 @@ EX void apply_always3() {
|
|||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
EX void switch_always3() {
|
EX void switch_always3() {
|
||||||
if(dual::split(switch_always3)) return;
|
if(dual::split(switch_always3)) return;
|
||||||
#if CAP_GL
|
#if CAP_GL && CAP_RUG
|
||||||
if(rug::rugged) rug::close();
|
if(rug::rugged) rug::close();
|
||||||
#endif
|
#endif
|
||||||
vid.always3 = !vid.always3;
|
vid.always3 = !vid.always3;
|
||||||
@ -946,7 +951,7 @@ EX void switch_always3() {
|
|||||||
|
|
||||||
EX void switch_fpp() {
|
EX void switch_fpp() {
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
#if CAP_GL
|
#if CAP_GL && CAP_RUG
|
||||||
if(rug::rugged) rug::close();
|
if(rug::rugged) rug::close();
|
||||||
#endif
|
#endif
|
||||||
if(dual::split(switch_fpp)) return;
|
if(dual::split(switch_fpp)) return;
|
||||||
@ -1026,7 +1031,9 @@ EX string cgi_string() {
|
|||||||
if(GOLDBERG_INV) V("GP", its(gp::param.first) + "," + its(gp::param.second));
|
if(GOLDBERG_INV) V("GP", its(gp::param.first) + "," + its(gp::param.second));
|
||||||
if(IRREGULAR) V("IRR", its(irr::irrid));
|
if(IRREGULAR) V("IRR", its(irr::irrid));
|
||||||
|
|
||||||
|
#if CAP_ARCM
|
||||||
if(arcm::in()) V("ARCM", arcm::current.symbol);
|
if(arcm::in()) V("ARCM", arcm::current.symbol);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(arb::in()) V("ARB", its(arb::current.order));
|
if(arb::in()) V("ARB", its(arb::current.order));
|
||||||
|
|
||||||
@ -1034,7 +1041,10 @@ EX string cgi_string() {
|
|||||||
|
|
||||||
if(bt::in() || GDIM == 3) V("WQ", its(vid.texture_step));
|
if(bt::in() || GDIM == 3) V("WQ", its(vid.texture_step));
|
||||||
|
|
||||||
if(hybri) V("U", its(int(hybrid::underlying)));
|
if(hybri) {
|
||||||
|
V("U", PIU(cgi_string()));
|
||||||
|
// its(int(hybrid::underlying)));
|
||||||
|
}
|
||||||
|
|
||||||
if(prod) V("PL", fts(vid.plevel_factor));
|
if(prod) V("PL", fts(vid.plevel_factor));
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ shiftmatrix &ggmatrix(cell *c);
|
|||||||
|
|
||||||
EX void fixelliptic(transmatrix& at) {
|
EX void fixelliptic(transmatrix& at) {
|
||||||
if(elliptic && at[LDIM][LDIM] < 0) {
|
if(elliptic && at[LDIM][LDIM] < 0) {
|
||||||
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++)
|
for(int i=0; i<MXDIM; i++) for(int j=0; j<MXDIM; j++)
|
||||||
at[i][j] = -at[i][j];
|
at[i][j] = -at[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void fixelliptic(hyperpoint& h) {
|
EX void fixelliptic(hyperpoint& h) {
|
||||||
if(elliptic && h[LDIM] < 0)
|
if(elliptic && h[LDIM] < 0)
|
||||||
for(int i=0; i<MDIM; i++) h[i] = -h[i];
|
for(int i=0; i<MXDIM; i++) h[i] = -h[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** find relative_matrix via recursing the tree structure */
|
/** find relative_matrix via recursing the tree structure */
|
||||||
@ -398,6 +398,7 @@ ld hrmap_standard::spin_angle(cell *c, int d) {
|
|||||||
ld hexshift = 0;
|
ld hexshift = 0;
|
||||||
if(c == c->master->c7 && (S7 % 2 == 0) && BITRUNCATED) hexshift = cgi.hexshift + 2*M_PI/c->type;
|
if(c == c->master->c7 && (S7 % 2 == 0) && BITRUNCATED) hexshift = cgi.hexshift + 2*M_PI/c->type;
|
||||||
else if(cgi.hexshift && c == c->master->c7) hexshift = cgi.hexshift;
|
else if(cgi.hexshift && c == c->master->c7) hexshift = cgi.hexshift;
|
||||||
|
#if CAP_IRR
|
||||||
if(IRREGULAR) {
|
if(IRREGULAR) {
|
||||||
auto id = irr::cellindex[c];
|
auto id = irr::cellindex[c];
|
||||||
auto& vs = irr::cells[id];
|
auto& vs = irr::cells[id];
|
||||||
@ -405,8 +406,8 @@ ld hrmap_standard::spin_angle(cell *c, int d) {
|
|||||||
auto& p = vs.jpoints[vs.neid[d]];
|
auto& p = vs.jpoints[vs.neid[d]];
|
||||||
return -atan2(p[1], p[0]) - hexshift;
|
return -atan2(p[1], p[0]) - hexshift;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
return M_PI - d * 2 * M_PI / c->type - hexshift;
|
return M_PI - d * 2 * M_PI / c->type - hexshift;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX transmatrix ddspin(cell *c, int d, ld bonus IS(0)) { return currentmap->spin_to(c, d, bonus); }
|
EX transmatrix ddspin(cell *c, int d, ld bonus IS(0)) { return currentmap->spin_to(c, d, bonus); }
|
||||||
@ -594,6 +595,7 @@ EX bool approx_nearcorner = false;
|
|||||||
|
|
||||||
EX hyperpoint nearcorner(cell *c, int i) {
|
EX hyperpoint nearcorner(cell *c, int i) {
|
||||||
if(GOLDBERG_INV) {
|
if(GOLDBERG_INV) {
|
||||||
|
i = gmod(i, c->type);
|
||||||
cellwalker cw(c, i);
|
cellwalker cw(c, i);
|
||||||
cw += wstep;
|
cw += wstep;
|
||||||
transmatrix cwm = currentmap->adj(c, i);
|
transmatrix cwm = currentmap->adj(c, i);
|
||||||
|
6
glhr.cpp
6
glhr.cpp
@ -154,7 +154,7 @@ void display(const glmatrix& m) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
glmatrix operator * (glmatrix m1, glmatrix m2) {
|
EX glmatrix operator * (glmatrix m1, glmatrix m2) {
|
||||||
glmatrix res;
|
glmatrix res;
|
||||||
for(int i=0; i<4; i++)
|
for(int i=0; i<4; i++)
|
||||||
for(int j=0; j<4; j++) {
|
for(int j=0; j<4; j++) {
|
||||||
@ -694,6 +694,10 @@ template<class T> void bindbuffer(T& v) {
|
|||||||
#define PTR(attrib, q, field) \
|
#define PTR(attrib, q, field) \
|
||||||
glVertexAttribPointer(attrib, q, GL_FLOAT, GL_FALSE, sizeof(v[0]), (void*) ((char*) &v[0].field - (char*) &v[0]));
|
glVertexAttribPointer(attrib, q, GL_FLOAT, GL_FALSE, sizeof(v[0]), (void*) ((char*) &v[0].field - (char*) &v[0]));
|
||||||
|
|
||||||
|
EX void bindbuffer_vertex(vector<glvertex>& v) {
|
||||||
|
bindbuffer(v);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EX void vertices(const vector<glvertex>& v, int vshift IS(0)) {
|
EX void vertices(const vector<glvertex>& v, int vshift IS(0)) {
|
||||||
|
@ -806,6 +806,7 @@ EX namespace gp {
|
|||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
|
|
||||||
|
#if CAP_IRR
|
||||||
if(irr::supports(geometry)) {
|
if(irr::supports(geometry)) {
|
||||||
dialog::addBoolItem(XLAT("irregular"), IRREGULAR, 'i');
|
dialog::addBoolItem(XLAT("irregular"), IRREGULAR, 'i');
|
||||||
dialog::add_action(dialog::add_confirmation([=] () {
|
dialog::add_action(dialog::add_confirmation([=] () {
|
||||||
@ -817,6 +818,7 @@ EX namespace gp {
|
|||||||
if(!IRREGULAR) irr::visual_creator();
|
if(!IRREGULAR) irr::visual_creator();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
int style = 0;
|
int style = 0;
|
||||||
@ -1126,6 +1128,8 @@ EX namespace gp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) override {
|
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) override {
|
||||||
|
c1 = mapping[c1];
|
||||||
|
c2 = mapping[c2];
|
||||||
return in_underlying([&] { return currentmap->relative_matrix(c2, c1, hint); });
|
return in_underlying([&] { return currentmap->relative_matrix(c2, c1, hint); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
graph.cpp
47
graph.cpp
@ -22,6 +22,8 @@ EX bool spatial_graphics;
|
|||||||
EX bool wmspatial, wmescher, wmplain, wmblack, wmascii, wmascii3;
|
EX bool wmspatial, wmescher, wmplain, wmblack, wmascii, wmascii3;
|
||||||
EX bool mmspatial, mmhigh, mmmon, mmitem;
|
EX bool mmspatial, mmhigh, mmmon, mmitem;
|
||||||
|
|
||||||
|
EX ld panini_alpha = 0;
|
||||||
|
|
||||||
EX int detaillevel = 0;
|
EX int detaillevel = 0;
|
||||||
|
|
||||||
EX bool first_cell_to_draw = true;
|
EX bool first_cell_to_draw = true;
|
||||||
@ -1020,7 +1022,11 @@ EX void drawTerraWarrior(const shiftmatrix& V, int t, int hp, double footphase)
|
|||||||
|
|
||||||
EX void drawPlayer(eMonster m, cell *where, const shiftmatrix& V, color_t col, double footphase, bool stop IS(false)) {
|
EX void drawPlayer(eMonster m, cell *where, const shiftmatrix& V, color_t col, double footphase, bool stop IS(false)) {
|
||||||
charstyle& cs = getcs();
|
charstyle& cs = getcs();
|
||||||
|
#if CAP_COMPLEX2
|
||||||
auto& knighted = camelot::knighted;
|
auto& knighted = camelot::knighted;
|
||||||
|
#else
|
||||||
|
const bool knighted = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(mapeditor::drawplayer && !mapeditor::drawUserShape(V, mapeditor::sgPlayer, cs.charid, cs.skincolor, where)) {
|
if(mapeditor::drawplayer && !mapeditor::drawUserShape(V, mapeditor::sgPlayer, cs.charid, cs.skincolor, where)) {
|
||||||
|
|
||||||
@ -1264,8 +1270,10 @@ void drawMimic(eMonster m, cell *where, const shiftmatrix& V, color_t col, doubl
|
|||||||
else if(!where || shmup::curtime >= shmup::getPlayer()->nextshot)
|
else if(!where || shmup::curtime >= shmup::getPlayer()->nextshot)
|
||||||
queuepoly(VBODY * VBS, cgi.shPKnife, darkena(col, 0, 0XC0));
|
queuepoly(VBODY * VBS, cgi.shPKnife, darkena(col, 0, 0XC0));
|
||||||
|
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(camelot::knighted)
|
if(camelot::knighted)
|
||||||
queuepoly(VBODY3 * VBS, cgi.shKnightCloak, darkena(col, 1, 0xC0));
|
queuepoly(VBODY3 * VBS, cgi.shKnightCloak, darkena(col, 1, 0xC0));
|
||||||
|
#endif
|
||||||
|
|
||||||
queuepoly(VHEAD1, (cs.charid&1) ? cgi.shFemaleHair : cgi.shPHead, darkena(col, 1, 0XC0));
|
queuepoly(VHEAD1, (cs.charid&1) ? cgi.shFemaleHair : cgi.shPHead, darkena(col, 1, 0XC0));
|
||||||
queuepoly(VHEAD, cgi.shPFace, darkena(col, 0, 0XC0));
|
queuepoly(VHEAD, cgi.shPFace, darkena(col, 0, 0XC0));
|
||||||
@ -3070,8 +3078,22 @@ EX void drawaura() {
|
|||||||
else rad0 *= m;
|
else rad0 *= m;
|
||||||
}
|
}
|
||||||
|
|
||||||
cx[r][z][0] = rad0 * c;
|
ld x = rad0 * c;
|
||||||
cx[r][z][1] = rad0 * s * pconf.stretch;
|
ld y = rad0 * s;
|
||||||
|
|
||||||
|
if(pconf.camera_angle) {
|
||||||
|
ld z = rad0;
|
||||||
|
|
||||||
|
ld cam = pconf.camera_angle * degree;
|
||||||
|
GLfloat cc = cos(cam);
|
||||||
|
GLfloat ss = sin(cam);
|
||||||
|
|
||||||
|
tie(y, z) = make_pair(y * cc - z * ss, z * cc + y * ss);
|
||||||
|
x *= rad0 / z;
|
||||||
|
y *= rad0 / z;
|
||||||
|
}
|
||||||
|
cx[r][z][0] = x;
|
||||||
|
cx[r][z][1] = y * pconf.stretch;
|
||||||
|
|
||||||
for(int u=0; u<3; u++)
|
for(int u=0; u<3; u++)
|
||||||
cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z];
|
cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z];
|
||||||
@ -3410,7 +3432,11 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool openorsafe(cell *c) {
|
bool openorsafe(cell *c) {
|
||||||
|
#if CAP_COMPLEX2
|
||||||
return c->wall == waMineOpen || mine::marked_safe(c);
|
return c->wall == waMineOpen || mine::marked_safe(c);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Dark(x) darkena(x,0,0xFF)
|
#define Dark(x) darkena(x,0,0xFF)
|
||||||
@ -3693,7 +3719,7 @@ EX bool frustum_culling = true;
|
|||||||
void make_clipping_planes() {
|
void make_clipping_planes() {
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
clipping_planes.clear();
|
clipping_planes.clear();
|
||||||
if(!frustum_culling || PIU(sphere) || experimental || vid.stereo_mode == sODS) return;
|
if(!frustum_culling || PIU(sphere) || experimental || vid.stereo_mode == sODS || panini_alpha) return;
|
||||||
auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) {
|
auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) {
|
||||||
ld z1 = 1, z2 = 1;
|
ld z1 = 1, z2 = 1;
|
||||||
hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1);
|
hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1);
|
||||||
@ -3788,7 +3814,9 @@ EX void gridline(const shiftmatrix& V, const hyperpoint h1, const hyperpoint h2,
|
|||||||
|
|
||||||
EX int wall_offset(cell *c) {
|
EX int wall_offset(cell *c) {
|
||||||
if(hybri || WDIM == 2) return hybrid::wall_offset(c);
|
if(hybri || WDIM == 2) return hybrid::wall_offset(c);
|
||||||
|
#if CAP_BT
|
||||||
if(kite::in() && kite::getshape(c->master) == kite::pKite) return 10;
|
if(kite::in() && kite::getshape(c->master) == kite::pKite) return 10;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4455,7 +4483,6 @@ EX bool allowChangeRange() {
|
|||||||
if(tour::on) return true;
|
if(tour::on) return true;
|
||||||
#endif
|
#endif
|
||||||
if(racing::on) return true;
|
if(racing::on) return true;
|
||||||
if(sightrange_bonus >= 0) return true;
|
|
||||||
if(arcm::in() || arb::in()) return true;
|
if(arcm::in() || arb::in()) return true;
|
||||||
if(WDIM == 3) return true;
|
if(WDIM == 3) return true;
|
||||||
return false;
|
return false;
|
||||||
@ -4866,7 +4893,8 @@ EX void calcparam() {
|
|||||||
cd->xcenter += cd->scrsize * pconf.xposition;
|
cd->xcenter += cd->scrsize * pconf.xposition;
|
||||||
cd->ycenter += cd->scrsize * pconf.yposition;
|
cd->ycenter += cd->scrsize * pconf.yposition;
|
||||||
|
|
||||||
cd->tanfov = tan(vid.fov * degree / 2);
|
ld fov = vid.fov * degree / 2;
|
||||||
|
cd->tanfov = sin(fov) / (cos(fov) + panini_alpha);
|
||||||
|
|
||||||
callhooks(hooks_calcparam);
|
callhooks(hooks_calcparam);
|
||||||
reset_projection();
|
reset_projection();
|
||||||
@ -4966,13 +4994,22 @@ EX void gamescreen(int _darken) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto cdc = *current_display;
|
||||||
|
auto gx = vid.xres;
|
||||||
|
auto gy = vid.yres;
|
||||||
|
|
||||||
if(dual::split([=] () {
|
if(dual::split([=] () {
|
||||||
|
*current_display = cdc;
|
||||||
|
vid.xres = gx;
|
||||||
|
vid.yres = gy;
|
||||||
dual::in_subscreen([=] () { gamescreen(_darken); });
|
dual::in_subscreen([=] () { gamescreen(_darken); });
|
||||||
})) {
|
})) {
|
||||||
calcparam();
|
calcparam();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calcparam();
|
||||||
|
|
||||||
if((cmode & sm::MAYDARK) && !current_display->sidescreen) {
|
if((cmode & sm::MAYDARK) && !current_display->sidescreen) {
|
||||||
_darken += 2;
|
_darken += 2;
|
||||||
}
|
}
|
||||||
|
12
help.cpp
12
help.cpp
@ -232,7 +232,7 @@ EX void buildCredits() {
|
|||||||
"Kojiguchi Kazuki, baconcow, Alan, SurelyYouJest, hotdogPi, DivisionByZero, xXxWeedGokuxXx, jpystynen, Dmitry Marakasov, Alexandre Moine, Arthur O'Dwyer, "
|
"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, "
|
"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, "
|
"Snakebird Priestess, roaringdragon2, Stopping Dog, bengineer8, Sir Light IJIJ, ShadeBlade, Saplou, shnourok, Ralith, madasa, 6% remaining, Chimera245, Remik Pi, alien foxcat thing, "
|
||||||
"Piotr Grochowski"
|
"Piotr Grochowski, Ann, still-flow"
|
||||||
);
|
);
|
||||||
#ifdef EXTRALICENSE
|
#ifdef EXTRALICENSE
|
||||||
help += EXTRALICENSE;
|
help += EXTRALICENSE;
|
||||||
@ -928,8 +928,12 @@ EX void describeMouseover() {
|
|||||||
if(isReptile(c->wall))
|
if(isReptile(c->wall))
|
||||||
out += " [" + turnstring((unsigned char) c->wparam) + "]";
|
out += " [" + turnstring((unsigned char) c->wparam) + "]";
|
||||||
|
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(c->monst == moKnight)
|
if(c->monst == moKnight)
|
||||||
out += XLAT(", %1 the Knight", camelot::knight_name(c));
|
out += XLAT(", %1 the Knight", camelot::knight_name(c));
|
||||||
|
#else
|
||||||
|
if(0) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
else if(c->monst) {
|
else if(c->monst) {
|
||||||
out += ", "; out += XLAT1(minf[c->monst].name);
|
out += ", "; out += XLAT1(minf[c->monst].name);
|
||||||
@ -950,10 +954,12 @@ EX void describeMouseover() {
|
|||||||
out += ", ";
|
out += ", ";
|
||||||
out += XLAT1(iinf[c->item].name);
|
out += XLAT1(iinf[c->item].name);
|
||||||
if(c->item == itBarrow) out += " (x" + its(c->landparam) + ")";
|
if(c->item == itBarrow) out += " (x" + its(c->landparam) + ")";
|
||||||
if(c->land == laHunting) {
|
#if CAP_COMPLEX2
|
||||||
|
if(c->land == laHunting) {
|
||||||
int i = ambush::size(c, c->item);
|
int i = ambush::size(c, c->item);
|
||||||
if(i) out += " (" + XLAT("ambush:") + " " + its(i) + ")";
|
if(i) out += " (" + XLAT("ambush:") + " " + its(i) + ")";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(c->item == itBabyTortoise && tortoise::seek())
|
if(c->item == itBabyTortoise && tortoise::seek())
|
||||||
out += " " + tortoise::measure(tortoise::babymap[c]);
|
out += " " + tortoise::measure(tortoise::babymap[c]);
|
||||||
if(!c->monst) set_help_to(c->item);
|
if(!c->monst) set_help_to(c->item);
|
||||||
@ -1000,12 +1006,14 @@ EX void describeMouseover() {
|
|||||||
callhooks(hooks_mouseover, c);
|
callhooks(hooks_mouseover, c);
|
||||||
|
|
||||||
if(mousey < vid.fsize * 3/2 && getcstat == '-' && !instat) getcstat = SDLK_F1;
|
if(mousey < vid.fsize * 3/2 && getcstat == '-' && !instat) getcstat = SDLK_F1;
|
||||||
|
#if CAP_TOUR
|
||||||
if(tour::on && !tour::texts) {
|
if(tour::on && !tour::texts) {
|
||||||
if(tour::slides[tour::currentslide].flags & tour::NOTITLE)
|
if(tour::slides[tour::currentslide].flags & tour::NOTITLE)
|
||||||
mouseovers = "";
|
mouseovers = "";
|
||||||
else
|
else
|
||||||
mouseovers = XLAT(tour::slides[tour::currentslide].name);
|
mouseovers = XLAT(tour::slides[tour::currentslide].name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void showHelp() {
|
EX void showHelp() {
|
||||||
|
@ -279,6 +279,12 @@ heptagon *hrmap_standard::create_step(heptagon *h, int d) {
|
|||||||
else
|
else
|
||||||
buildHeptagon(h, d, transition(h->s, d));
|
buildHeptagon(h, d, transition(h->s, d));
|
||||||
}
|
}
|
||||||
|
else if(S3 > 4 && quotient) {
|
||||||
|
/* this branch may be used for some >4-valent quotient spaces outside of standard HyperRogue */
|
||||||
|
/* this is wrong, but we don't care in quotient */
|
||||||
|
h->move(d) = h;
|
||||||
|
// buildHeptagon(h, d, transition(h->s, d));
|
||||||
|
}
|
||||||
else if(d == 1) {
|
else if(d == 1) {
|
||||||
addSpin(h, d, h->move(0), h->c.spin(0)-1, -1);
|
addSpin(h, d, h->move(0), h->c.spin(0)-1, -1);
|
||||||
}
|
}
|
||||||
|
1
hud.cpp
1
hud.cpp
@ -228,6 +228,7 @@ bool displayglyph(int cx, int cy, int buttonsize, char glyph, color_t color, int
|
|||||||
glyphphase[id] * 2;
|
glyphphase[id] * 2;
|
||||||
drawItemType(it, NULL, shiftless(V), icol, t, false);
|
drawItemType(it, NULL, shiftless(V), icol, t, false);
|
||||||
}
|
}
|
||||||
|
sortquickqueue();
|
||||||
quickqueue();
|
quickqueue();
|
||||||
}
|
}
|
||||||
else if(glyph == '*')
|
else if(glyph == '*')
|
||||||
|
18
hyper.h
18
hyper.h
@ -13,8 +13,8 @@
|
|||||||
#define _HYPER_H_
|
#define _HYPER_H_
|
||||||
|
|
||||||
// version numbers
|
// version numbers
|
||||||
#define VER "11.3ż"
|
#define VER "11.4a"
|
||||||
#define VERNUM_HEX 0xA83B
|
#define VERNUM_HEX 0xA841
|
||||||
|
|
||||||
#include "sysconfig.h"
|
#include "sysconfig.h"
|
||||||
|
|
||||||
@ -48,7 +48,6 @@ template<class T, class V, class... U> bool among(T x, V y, U... u) { return x==
|
|||||||
using std::vector;
|
using std::vector;
|
||||||
using std::map;
|
using std::map;
|
||||||
using std::array;
|
using std::array;
|
||||||
using std::unordered_map;
|
|
||||||
using std::sort;
|
using std::sort;
|
||||||
using std::multimap;
|
using std::multimap;
|
||||||
using std::set;
|
using std::set;
|
||||||
@ -242,6 +241,7 @@ struct projection_configuration {
|
|||||||
ld model_orientation, halfplane_scale, model_orientation_yz;
|
ld model_orientation, halfplane_scale, model_orientation_yz;
|
||||||
ld collignon_parameter;
|
ld collignon_parameter;
|
||||||
ld aitoff_parameter, miller_parameter, loximuthal_parameter, winkel_parameter;
|
ld aitoff_parameter, miller_parameter, loximuthal_parameter, winkel_parameter;
|
||||||
|
bool show_hyperboloid_flat;
|
||||||
bool collignon_reflected;
|
bool collignon_reflected;
|
||||||
string formula;
|
string formula;
|
||||||
eModel basic_model;
|
eModel basic_model;
|
||||||
@ -272,6 +272,7 @@ struct projection_configuration {
|
|||||||
miller_parameter = .8;
|
miller_parameter = .8;
|
||||||
loximuthal_parameter = 0;
|
loximuthal_parameter = 0;
|
||||||
winkel_parameter = .5;
|
winkel_parameter = .5;
|
||||||
|
show_hyperboloid_flat = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -383,16 +384,23 @@ struct videopar {
|
|||||||
|
|
||||||
extern videopar vid;
|
extern videopar vid;
|
||||||
|
|
||||||
|
/** \brief How many dimensional is the gameplay. In the FPP mode of a 2D geometry, WDIM is 2 */
|
||||||
#define WDIM cginf.g.gameplay_dimension
|
#define WDIM cginf.g.gameplay_dimension
|
||||||
|
/** \brief How many dimensional is the graphical representation. In the FPP mode of a 2D geometry, MDIM is 3 */
|
||||||
#define GDIM cginf.g.graphical_dimension
|
#define GDIM cginf.g.graphical_dimension
|
||||||
|
/** \brief How many dimensions of the matrix representation are used. It is usually 3 in 2D geometries (not FPP) and in product geometries, 4 in 3D geometries */
|
||||||
#define MDIM (MAXMDIM == 3 ? 3 : cginf.g.homogeneous_dimension)
|
#define MDIM (MAXMDIM == 3 ? 3 : cginf.g.homogeneous_dimension)
|
||||||
|
/** \brief What dimension of matrices is used in loops (the 'extra' dimensions have values 0 or 1 as in Id)
|
||||||
|
* Even if MDIM==3, it may be faster to keep 4x4 matrices and perform computations using them (rather than having another condition due to the variable loop size).
|
||||||
|
* The experiments on my computer show it to be the case, but the effect is not significant, and it may be different on another computer.
|
||||||
|
*/
|
||||||
|
#define MXDIM (CAP_MDIM_FIXED ? MAXMDIM : MDIM)
|
||||||
|
/** \brief The 'homogeneous' dimension index */
|
||||||
#define LDIM (MDIM-1)
|
#define LDIM (MDIM-1)
|
||||||
#define cclass g.kind
|
#define cclass g.kind
|
||||||
|
|
||||||
#define self (*this)
|
#define self (*this)
|
||||||
|
|
||||||
// #define MODFIXER (2*10090080*17)
|
|
||||||
|
|
||||||
#define BUGCOLORS 3
|
#define BUGCOLORS 3
|
||||||
|
|
||||||
#define big_unlock (inv::on && !chaosmode)
|
#define big_unlock (inv::on && !chaosmode)
|
||||||
|
107
hyperpoint.cpp
107
hyperpoint.cpp
@ -59,22 +59,22 @@ struct hyperpoint : array<ld, MAXMDIM> {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline hyperpoint& operator *= (ld d) {
|
inline hyperpoint& operator *= (ld d) {
|
||||||
for(int i=0; i<MDIM; i++) self[i] *= d;
|
for(int i=0; i<MXDIM; i++) self[i] *= d;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hyperpoint& operator /= (ld d) {
|
inline hyperpoint& operator /= (ld d) {
|
||||||
for(int i=0; i<MDIM; i++) self[i] /= d;
|
for(int i=0; i<MXDIM; i++) self[i] /= d;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hyperpoint& operator += (const hyperpoint h2) {
|
inline hyperpoint& operator += (const hyperpoint h2) {
|
||||||
for(int i=0; i<MDIM; i++) self[i] += h2[i];
|
for(int i=0; i<MXDIM; i++) self[i] += h2[i];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hyperpoint& operator -= (const hyperpoint h2) {
|
inline hyperpoint& operator -= (const hyperpoint h2) {
|
||||||
for(int i=0; i<MDIM; i++) self[i] -= h2[i];
|
for(int i=0; i<MXDIM; i++) self[i] -= h2[i];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ struct hyperpoint : array<ld, MAXMDIM> {
|
|||||||
// inner product
|
// inner product
|
||||||
inline friend ld operator | (hyperpoint h1, hyperpoint h2) {
|
inline friend ld operator | (hyperpoint h1, hyperpoint h2) {
|
||||||
ld sum = 0;
|
ld sum = 0;
|
||||||
for(int i=0; i<MDIM; i++) sum += h1[i] * h2[i];
|
for(int i=0; i<MXDIM; i++) sum += h1[i] * h2[i];
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -118,18 +118,18 @@ struct transmatrix {
|
|||||||
|
|
||||||
inline friend hyperpoint operator * (const transmatrix& T, const hyperpoint& H) {
|
inline friend hyperpoint operator * (const transmatrix& T, const hyperpoint& H) {
|
||||||
hyperpoint z;
|
hyperpoint z;
|
||||||
for(int i=0; i<MDIM; i++) {
|
for(int i=0; i<MXDIM; i++) {
|
||||||
z[i] = 0;
|
z[i] = 0;
|
||||||
for(int j=0; j<MDIM; j++) z[i] += T[i][j] * H[j];
|
for(int j=0; j<MXDIM; j++) z[i] += T[i][j] * H[j];
|
||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline friend transmatrix operator * (const transmatrix& T, const transmatrix& U) {
|
inline friend transmatrix operator * (const transmatrix& T, const transmatrix& U) {
|
||||||
transmatrix R;
|
transmatrix R;
|
||||||
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++) {
|
for(int i=0; i<MXDIM; i++) for(int j=0; j<MXDIM; j++) {
|
||||||
R[i][j] = 0;
|
R[i][j] = 0;
|
||||||
for(int k=0; k<MDIM; k++)
|
for(int k=0; k<MXDIM; k++)
|
||||||
R[i][j] += T[i][k] * U[k][j];
|
R[i][j] += T[i][k] * U[k][j];
|
||||||
}
|
}
|
||||||
return R;
|
return R;
|
||||||
@ -490,14 +490,14 @@ EX ld hypot_auto(ld x, ld y) {
|
|||||||
EX hyperpoint normalize(hyperpoint H) {
|
EX hyperpoint normalize(hyperpoint H) {
|
||||||
if(prod) return H;
|
if(prod) return H;
|
||||||
ld Z = zlevel(H);
|
ld Z = zlevel(H);
|
||||||
for(int c=0; c<MDIM; c++) H[c] /= Z;
|
for(int c=0; c<MXDIM; c++) H[c] /= Z;
|
||||||
return H;
|
return H;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** like normalize but makes (ultra)ideal points material */
|
/** like normalize but makes (ultra)ideal points material */
|
||||||
EX hyperpoint ultra_normalize(hyperpoint H) {
|
EX hyperpoint ultra_normalize(hyperpoint H) {
|
||||||
if(material(H) <= 0) {
|
if(material(H) <= 0) {
|
||||||
H[MDIM-1] = hypot_d(MDIM-1, H) + 1e-6;
|
H[LDIM] = hypot_d(LDIM, H) + 1e-6;
|
||||||
}
|
}
|
||||||
return normalize(H);
|
return normalize(H);
|
||||||
}
|
}
|
||||||
@ -531,7 +531,7 @@ EX hyperpoint midz(const hyperpoint& H1, const hyperpoint& H2) {
|
|||||||
ld Z = 2;
|
ld Z = 2;
|
||||||
|
|
||||||
if(!euclid) Z = zlevel(H3) * 2 / (zlevel(H1) + zlevel(H2));
|
if(!euclid) Z = zlevel(H3) * 2 / (zlevel(H1) + zlevel(H2));
|
||||||
for(int c=0; c<MDIM; c++) H3[c] /= Z;
|
for(int c=0; c<MXDIM; c++) H3[c] /= Z;
|
||||||
|
|
||||||
return H3;
|
return H3;
|
||||||
}
|
}
|
||||||
@ -611,8 +611,8 @@ EX transmatrix cpush(int cid, ld alpha) {
|
|||||||
EX transmatrix xpush(ld alpha) { return cpush(0, alpha); }
|
EX transmatrix xpush(ld alpha) { return cpush(0, alpha); }
|
||||||
|
|
||||||
EX bool eqmatrix(transmatrix A, transmatrix B, ld eps IS(.01)) {
|
EX bool eqmatrix(transmatrix A, transmatrix B, ld eps IS(.01)) {
|
||||||
for(int i=0; i<MDIM; i++)
|
for(int i=0; i<MXDIM; i++)
|
||||||
for(int j=0; j<MDIM; j++)
|
for(int j=0; j<MXDIM; j++)
|
||||||
if(std::abs(A[i][j] - B[i][j]) > eps)
|
if(std::abs(A[i][j] - B[i][j]) > eps)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -702,7 +702,7 @@ EX transmatrix parabolic13(ld u, ld v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX hyperpoint parabolic10(hyperpoint h) {
|
EX hyperpoint parabolic10(hyperpoint h) {
|
||||||
if(euclid) { h[MDIM] = 1; return h; }
|
if(euclid) { h[LDIM] = 1; return h; }
|
||||||
else if(MDIM == 4) return hyperpoint(sinh(h[0]), h[1]/exp(h[0]), h[2]/exp(h[0]), cosh(h[0]));
|
else if(MDIM == 4) return hyperpoint(sinh(h[0]), h[1]/exp(h[0]), h[2]/exp(h[0]), cosh(h[0]));
|
||||||
else return hyperpoint(sinh(h[0]), h[1]/exp(h[0]), cosh(h[0]), 0);
|
else return hyperpoint(sinh(h[0]), h[1]/exp(h[0]), cosh(h[0]), 0);
|
||||||
}
|
}
|
||||||
@ -768,18 +768,19 @@ EX transmatrix pushxto0(const hyperpoint& H) {
|
|||||||
|
|
||||||
/** set the i-th column of T to H */
|
/** set the i-th column of T to H */
|
||||||
EX void set_column(transmatrix& T, int i, const hyperpoint& H) {
|
EX void set_column(transmatrix& T, int i, const hyperpoint& H) {
|
||||||
for(int j=0; j<MDIM; j++)
|
for(int j=0; j<MXDIM; j++)
|
||||||
T[j][i] = H[j];
|
T[j][i] = H[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** build a matrix using the given vectors as columns */
|
/** build a matrix using the given vectors as columns */
|
||||||
EX transmatrix build_matrix(hyperpoint h1, hyperpoint h2, hyperpoint h3, hyperpoint h4) {
|
EX transmatrix build_matrix(hyperpoint h1, hyperpoint h2, hyperpoint h3, hyperpoint h4) {
|
||||||
transmatrix T;
|
transmatrix T;
|
||||||
for(int i=0; i<MDIM; i++)
|
for(int i=0; i<MXDIM; i++) {
|
||||||
T[i][0] = h1[i],
|
T[i][0] = h1[i],
|
||||||
T[i][1] = h2[i],
|
T[i][1] = h2[i],
|
||||||
T[i][2] = h3[i];
|
T[i][2] = h3[i];
|
||||||
if(MAXMDIM == 4) for(int i=0; i<MDIM; i++) T[i][3] = h4[i];
|
if(MAXMDIM == 4) T[i][3] = h4[i];
|
||||||
|
}
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,11 +869,11 @@ EX void fixmatrix_euclid(transmatrix& T) {
|
|||||||
EX void orthonormalize(transmatrix& T) {
|
EX void orthonormalize(transmatrix& T) {
|
||||||
for(int x=0; x<MDIM; x++) for(int y=0; y<=x; y++) {
|
for(int x=0; x<MDIM; x++) for(int y=0; y<=x; y++) {
|
||||||
ld dp = 0;
|
ld dp = 0;
|
||||||
for(int z=0; z<MDIM; z++) dp += T[z][x] * T[z][y] * sig(z);
|
for(int z=0; z<MXDIM; z++) dp += T[z][x] * T[z][y] * sig(z);
|
||||||
|
|
||||||
if(y == x) dp = 1 - sqrt(sig(x)/dp);
|
if(y == x) dp = 1 - sqrt(sig(x)/dp);
|
||||||
|
|
||||||
for(int z=0; z<MDIM; z++) T[z][x] -= dp * T[z][y];
|
for(int z=0; z<MXDIM; z++) T[z][x] -= dp * T[z][y];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,20 +894,20 @@ EX ld det3(const transmatrix& T) {
|
|||||||
|
|
||||||
/** determinant */
|
/** determinant */
|
||||||
EX ld det(const transmatrix& T) {
|
EX ld det(const transmatrix& T) {
|
||||||
if(GDIM == 2)
|
if(MDIM == 3)
|
||||||
return det3(T);
|
return det3(T);
|
||||||
else {
|
else {
|
||||||
ld det = 1;
|
ld det = 1;
|
||||||
transmatrix M = T;
|
transmatrix M = T;
|
||||||
for(int a=0; a<MDIM; a++) {
|
for(int a=0; a<MDIM; a++) {
|
||||||
for(int b=a; b<=GDIM; b++)
|
for(int b=a; b<MDIM; b++)
|
||||||
if(M[b][a]) {
|
if(M[b][a]) {
|
||||||
if(b != a)
|
if(b != a)
|
||||||
for(int c=a; c<MDIM; c++) tie(M[b][c], M[a][c]) = make_pair(-M[a][c], M[b][c]);
|
for(int c=a; c<MDIM; c++) tie(M[b][c], M[a][c]) = make_pair(-M[a][c], M[b][c]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!M[a][a]) return 0;
|
if(!M[a][a]) return 0;
|
||||||
for(int b=a+1; b<=GDIM; b++) {
|
for(int b=a+1; b<MDIM; b++) {
|
||||||
ld co = -M[b][a] / M[a][a];
|
ld co = -M[b][a] / M[a][a];
|
||||||
for(int c=a; c<MDIM; c++) M[b][c] += M[a][c] * co;
|
for(int c=a; c<MDIM; c++) M[b][c] += M[a][c] * co;
|
||||||
}
|
}
|
||||||
@ -986,7 +987,7 @@ EX transmatrix ortho_inverse(transmatrix T) {
|
|||||||
|
|
||||||
/** \brief inverse of an orthogonal matrix in Minkowski space */
|
/** \brief inverse of an orthogonal matrix in Minkowski space */
|
||||||
EX transmatrix pseudo_ortho_inverse(transmatrix T) {
|
EX transmatrix pseudo_ortho_inverse(transmatrix T) {
|
||||||
for(int i=1; i<MDIM; i++)
|
for(int i=1; i<MXDIM; i++)
|
||||||
for(int j=0; j<i; j++)
|
for(int j=0; j<i; j++)
|
||||||
swap(T[i][j], T[j][i]);
|
swap(T[i][j], T[j][i]);
|
||||||
for(int i=0; i<MDIM-1; i++)
|
for(int i=0; i<MDIM-1; i++)
|
||||||
@ -1127,7 +1128,7 @@ EX hyperpoint mscale(const hyperpoint& t, double fac) {
|
|||||||
if(GDIM == 3 && !prod) return cpush(2, fac) * t;
|
if(GDIM == 3 && !prod) return cpush(2, fac) * t;
|
||||||
if(prod) fac = exp(fac);
|
if(prod) fac = exp(fac);
|
||||||
hyperpoint res;
|
hyperpoint res;
|
||||||
for(int i=0; i<MDIM; i++)
|
for(int i=0; i<MXDIM; i++)
|
||||||
res[i] = t[i] * fac;
|
res[i] = t[i] * fac;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1143,8 +1144,12 @@ EX transmatrix mscale(const transmatrix& t, double fac) {
|
|||||||
}
|
}
|
||||||
if(prod) fac = exp(fac);
|
if(prod) fac = exp(fac);
|
||||||
transmatrix res;
|
transmatrix res;
|
||||||
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++)
|
for(int i=0; i<MXDIM; i++) {
|
||||||
res[i][j] = t[i][j] * fac;
|
for(int j=0; j<MDIM; j++)
|
||||||
|
res[i][j] = t[i][j] * fac;
|
||||||
|
for(int j=MDIM; j<MXDIM; j++)
|
||||||
|
res[i][j] = t[i][j];
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,17 +1159,25 @@ EX shiftmatrix mscale(const shiftmatrix& t, double fac) {
|
|||||||
|
|
||||||
EX transmatrix xyscale(const transmatrix& t, double fac) {
|
EX transmatrix xyscale(const transmatrix& t, double fac) {
|
||||||
transmatrix res;
|
transmatrix res;
|
||||||
for(int i=0; i<MDIM; i++) for(int j=0; j<GDIM; j++)
|
for(int i=0; i<MXDIM; i++) {
|
||||||
res[i][j] = t[i][j] * fac;
|
for(int j=0; j<GDIM; j++)
|
||||||
|
res[i][j] = t[i][j] * fac;
|
||||||
|
for(int j=GDIM; j<MXDIM; j++)
|
||||||
|
res[i][j] = t[i][j];
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX transmatrix xyzscale(const transmatrix& t, double fac, double facz) {
|
EX transmatrix xyzscale(const transmatrix& t, double fac, double facz) {
|
||||||
transmatrix res;
|
transmatrix res;
|
||||||
for(int i=0; i<MDIM; i++) for(int j=0; j<GDIM; j++)
|
for(int i=0; i<MXDIM; i++) {
|
||||||
res[i][j] = t[i][j] * fac;
|
for(int j=0; j<GDIM; j++)
|
||||||
for(int i=0; i<MDIM; i++)
|
res[i][j] = t[i][j] * fac;
|
||||||
res[i][LDIM] = t[i][LDIM] * facz;
|
res[i][LDIM] =
|
||||||
|
t[i][LDIM] * facz;
|
||||||
|
for(int j=LDIM+1; j<MXDIM; j++)
|
||||||
|
res[i][j] = t[i][j];
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,7 +1194,7 @@ EX transmatrix mzscale(const transmatrix& t, double fac) {
|
|||||||
transmatrix res = t * inverse(tcentered) * ypush(-fac) * tcentered;
|
transmatrix res = t * inverse(tcentered) * ypush(-fac) * tcentered;
|
||||||
fac *= .2;
|
fac *= .2;
|
||||||
fac += 1;
|
fac += 1;
|
||||||
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++)
|
for(int i=0; i<MXDIM; i++) for(int j=0; j<MXDIM; j++)
|
||||||
res[i][j] = res[i][j] * fac;
|
res[i][j] = res[i][j] * fac;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1300,8 +1313,8 @@ EX ld ortho_error(transmatrix T) {
|
|||||||
|
|
||||||
EX transmatrix transpose(transmatrix T) {
|
EX transmatrix transpose(transmatrix T) {
|
||||||
transmatrix result;
|
transmatrix result;
|
||||||
for(int i=0; i<MDIM; i++)
|
for(int i=0; i<MXDIM; i++)
|
||||||
for(int j=0; j<MDIM; j++)
|
for(int j=0; j<MXDIM; j++)
|
||||||
result[j][i] = T[i][j];
|
result[j][i] = T[i][j];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1340,7 +1353,7 @@ inline hyperpoint zpush0(ld x) { return cpush0(2, x); }
|
|||||||
/** T * C0, optimized */
|
/** T * C0, optimized */
|
||||||
inline hyperpoint tC0(const transmatrix &T) {
|
inline hyperpoint tC0(const transmatrix &T) {
|
||||||
hyperpoint z;
|
hyperpoint z;
|
||||||
for(int i=0; i<MDIM; i++) z[i] = T[i][LDIM];
|
for(int i=0; i<MXDIM; i++) z[i] = T[i][LDIM];
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1485,4 +1498,24 @@ EX hyperpoint lerp(hyperpoint a0, hyperpoint a1, ld x) {
|
|||||||
return a0 + (a1-a0) * x;
|
return a0 + (a1-a0) * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX hyperpoint linecross(hyperpoint a, hyperpoint b, hyperpoint c, hyperpoint d) {
|
||||||
|
a /= a[LDIM];
|
||||||
|
b /= b[LDIM];
|
||||||
|
c /= c[LDIM];
|
||||||
|
d /= d[LDIM];
|
||||||
|
|
||||||
|
ld bax = b[0] - a[0];
|
||||||
|
ld dcx = d[0] - c[0];
|
||||||
|
ld cax = c[0] - a[0];
|
||||||
|
ld bay = b[1] - a[1];
|
||||||
|
ld dcy = d[1] - c[1];
|
||||||
|
ld cay = c[1] - a[1];
|
||||||
|
|
||||||
|
hyperpoint res;
|
||||||
|
res[0] = (cay * dcx * bax + a[0] * bay * dcx - c[0] * dcy * bax) / (bay * dcx - dcy * bax);
|
||||||
|
res[1] = (cax * dcy * bay + a[1] * bax * dcy - c[1] * dcx * bay) / (bax * dcy - dcx * bay);
|
||||||
|
res[2] = 1;
|
||||||
|
return normalize(res);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
56
hyperweb.cpp
56
hyperweb.cpp
@ -2,21 +2,16 @@
|
|||||||
// This is the main file when the online version of HyperRogue is compiled with Emscripten.
|
// This is the main file when the online version of HyperRogue is compiled with Emscripten.
|
||||||
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
|
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
|
||||||
|
|
||||||
|
#ifndef ISWEB
|
||||||
#define ISWEB 1
|
#define ISWEB 1
|
||||||
#define ISMINI 0
|
#define ISMINI 0
|
||||||
#define CAP_AUDIO 0
|
|
||||||
#define CAP_SDLGFX 0
|
|
||||||
#define CAP_PNG 0
|
|
||||||
#define CAP_TOUR 1
|
|
||||||
#define CAP_SDLTTF 0
|
|
||||||
#define CAP_SHMUP 0
|
|
||||||
#define CAP_RUG 1
|
|
||||||
#define CAP_INV 0
|
#define CAP_INV 0
|
||||||
#define CAP_URL 1
|
#define CAP_URL 1
|
||||||
#define GLES_ONLY
|
#define GLES_ONLY
|
||||||
#define CAP_COMPLEX2 1
|
#define SCU
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CAP_ROGUEVIZ
|
#if CAP_ROGUEVIZ || defined(MAXMDIM)
|
||||||
#define MAXMDIM 4
|
#define MAXMDIM 4
|
||||||
#else
|
#else
|
||||||
#define MAXMDIM 3
|
#define MAXMDIM 3
|
||||||
@ -45,6 +40,7 @@ namespace hr {
|
|||||||
void emscripten_get_commandline();
|
void emscripten_get_commandline();
|
||||||
|
|
||||||
void loadCompressedChar(int &otwidth, int &otheight, int *tpix);
|
void loadCompressedChar(int &otwidth, int &otheight, int *tpix);
|
||||||
|
void get_canvas_size();
|
||||||
|
|
||||||
const char *wheresounds;
|
const char *wheresounds;
|
||||||
|
|
||||||
@ -53,7 +49,11 @@ namespace hr {
|
|||||||
void offer_download(std::string sfilename, std::string smimetype);
|
void offer_download(std::string sfilename, std::string smimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SCU
|
||||||
#include "hyper.cpp"
|
#include "hyper.cpp"
|
||||||
|
#else
|
||||||
|
#include "hyper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ string get_value(string name) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void offer_download(string sfilename, string smimetype) {
|
EX void offer_download(string sfilename, string smimetype) {
|
||||||
|
|
||||||
EM_ASM({
|
EM_ASM({
|
||||||
var name = UTF8ToString($0, $1);
|
var name = UTF8ToString($0, $1);
|
||||||
@ -105,7 +105,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void offer_choose_file(reaction_t r) {
|
EX void offer_choose_file(reaction_t r) {
|
||||||
on_use_file = r;
|
on_use_file = r;
|
||||||
EM_ASM({
|
EM_ASM({
|
||||||
fileElem.click();
|
fileElem.click();
|
||||||
@ -221,9 +221,39 @@ EM_BOOL fsc_callback(int eventType, const EmscriptenFullscreenChangeEvent *fulls
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initweb() {
|
EX void get_canvas_size() {
|
||||||
|
vid.xscr = vid.xres = EM_ASM_INT({
|
||||||
|
var d = document.getElementById("this_wide");
|
||||||
|
if(!d) return window.innerWidth;
|
||||||
|
return d.clientWidth;
|
||||||
|
});
|
||||||
|
if(vid.full) vid.yscr = vid.yres = EM_ASM_INT({
|
||||||
|
var d = document.getElementById("this_wide");
|
||||||
|
if(!d) return window.innerWidth;
|
||||||
|
return d.clientHeight;
|
||||||
|
});
|
||||||
|
else {
|
||||||
|
vid.xscr = vid.xres = vid.xres - 32;
|
||||||
|
vid.yscr = vid.yres = EM_ASM_INT({
|
||||||
|
return window.innerHeight;
|
||||||
|
}) - 32;
|
||||||
|
vid.yscr = vid.yres = min(vid.yscr, vid.xscr * 9 / 16);
|
||||||
|
vid.xscr = vid.xres = min(vid.xscr, vid.yscr * 16 / 9);
|
||||||
|
}
|
||||||
|
println(hlog, "X = ", vid.xscr, " Y = ", vid.yscr);
|
||||||
|
}
|
||||||
|
|
||||||
|
EM_BOOL resize_callback(int eventType, const EmscriptenUiEvent *resizeEvent, void *userData) {
|
||||||
|
if(vid.full) return true;
|
||||||
|
get_canvas_size();
|
||||||
|
setvideomode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EX void initweb() {
|
||||||
// toggleanim(false);
|
// toggleanim(false);
|
||||||
emscripten_set_fullscreenchange_callback(0, NULL, false, fsc_callback);
|
emscripten_set_fullscreenchange_callback(0, NULL, false, fsc_callback);
|
||||||
|
emscripten_set_resize_callback(0, NULL, false, resize_callback);
|
||||||
printf("showstartmenu = %d\n", showstartmenu);
|
printf("showstartmenu = %d\n", showstartmenu);
|
||||||
if(showstartmenu) pushScreen(showDemo);
|
if(showstartmenu) pushScreen(showDemo);
|
||||||
}
|
}
|
||||||
@ -241,7 +271,7 @@ transmatrix getOrientation() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void emscripten_get_commandline() {
|
EX void emscripten_get_commandline() {
|
||||||
#ifdef EMSCRIPTEN_FIXED_ARG
|
#ifdef EMSCRIPTEN_FIXED_ARG
|
||||||
string s = EMSCRIPTEN_FIXED_ARG;
|
string s = EMSCRIPTEN_FIXED_ARG;
|
||||||
#else
|
#else
|
||||||
|
75
hypgraph.cpp
75
hypgraph.cpp
@ -1074,6 +1074,76 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case mdRetroCraig: {
|
||||||
|
makeband(H_orig, ret, [] (ld& x, ld& y) {
|
||||||
|
if(x)
|
||||||
|
y = x / sin_auto(x) * (sin_auto(y) * cos_auto(x) - tan_auto(pconf.loximuthal_parameter) * cos_auto(y));
|
||||||
|
else
|
||||||
|
y = sin_auto(y) - tan_auto(pconf.loximuthal_parameter) * cos_auto(y);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case mdRetroLittrow: {
|
||||||
|
makeband(H_orig, ret, [] (ld& x, ld& y) {
|
||||||
|
tie(x, y) = make_pair(
|
||||||
|
sin_auto(x) / cos_auto(y),
|
||||||
|
cos_auto(x) * tan_auto(y)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case mdRetroHammer: {
|
||||||
|
ld d = hdist(H, ypush0(pconf.loximuthal_parameter));
|
||||||
|
makeband(H_orig, ret, [d,H] (ld& x, ld& y) {
|
||||||
|
if(x == 0 && y == 0) return;
|
||||||
|
|
||||||
|
if(x)
|
||||||
|
y = x / sin_auto(x) * (sin_auto(y) * cos_auto(x) - tan_auto(pconf.loximuthal_parameter) * cos_auto(y));
|
||||||
|
else
|
||||||
|
y = sin_auto(y) - tan_auto(pconf.loximuthal_parameter) * cos_auto(y);
|
||||||
|
|
||||||
|
ld scale = d / hypot(x, y);
|
||||||
|
if(H[2] < 0) scale = -scale;
|
||||||
|
x *= scale;
|
||||||
|
y *= scale;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case mdPanini: {
|
||||||
|
ld proh = sqrt(H[2]*H[2] + curvature() * H[0] * H[0]);
|
||||||
|
H /= proh;
|
||||||
|
H /= (H[2] + pconf.alpha);
|
||||||
|
ret = H;
|
||||||
|
ret[2] = 0; ret[3] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case mdPoorMan: {
|
||||||
|
find_zlev(H);
|
||||||
|
H = space_to_perspective(H);
|
||||||
|
|
||||||
|
models::apply_orientation_yz(H[1], H[2]);
|
||||||
|
models::apply_orientation(H[0], H[1]);
|
||||||
|
|
||||||
|
ld u = H[0], v = H[1];
|
||||||
|
if(abs(u) > 1e-3 && abs(v) > 1e-3) {
|
||||||
|
ld r2 = u*u+v*v;
|
||||||
|
ld scale = sqrt((-r2+sqrt(r2*(r2+4*u*u*v*v*(r2-2))))/(2*(r2-2))) / u / v;
|
||||||
|
if(u*v<0) scale = -scale;
|
||||||
|
H = scale * H;
|
||||||
|
}
|
||||||
|
ret = H;
|
||||||
|
ret[2] = 0;
|
||||||
|
ret[3] = 1;
|
||||||
|
|
||||||
|
models::apply_orientation(ret[1], ret[0]);
|
||||||
|
models::apply_orientation_yz(ret[2], ret[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case mdGUARD: case mdManual: break;
|
case mdGUARD: case mdManual: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1462,6 +1532,10 @@ void hrmap::draw_at(cell *at, const shiftmatrix& where) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void hrmap_standard::draw_at(cell *at, const shiftmatrix& where) {
|
void hrmap_standard::draw_at(cell *at, const shiftmatrix& where) {
|
||||||
|
if(S3 > 4) {
|
||||||
|
hrmap::draw_at(at, where);
|
||||||
|
return;
|
||||||
|
}
|
||||||
drawn_cells.clear();
|
drawn_cells.clear();
|
||||||
drawn_cells.emplace_back(at->master, hsOrigin, where * master_relative(at, true));
|
drawn_cells.emplace_back(at->master, hsOrigin, where * master_relative(at, true));
|
||||||
for(int i=0; i<isize(drawn_cells); i++) {
|
for(int i=0; i<isize(drawn_cells); i++) {
|
||||||
@ -1926,6 +2000,7 @@ EX void draw_model_elements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case mdHyperboloid: {
|
case mdHyperboloid: {
|
||||||
|
if(!pconf.show_hyperboloid_flat) return;
|
||||||
if(hyperbolic) {
|
if(hyperbolic) {
|
||||||
#if CAP_QUEUE
|
#if CAP_QUEUE
|
||||||
curvepoint(point3(0,0,1));
|
curvepoint(point3(0,0,1));
|
||||||
|
34
items.cpp
34
items.cpp
@ -313,6 +313,8 @@ EX void dropGreenStone(cell *c) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(items[itGreenStone] && c->item == itNone) {
|
if(items[itGreenStone] && c->item == itNone) {
|
||||||
|
changes.ccell(c);
|
||||||
|
changes.value_keep(items[itGreenStone]);
|
||||||
items[itGreenStone]--;
|
items[itGreenStone]--;
|
||||||
if(false) {
|
if(false) {
|
||||||
c->item = itNone;
|
c->item = itNone;
|
||||||
@ -484,21 +486,23 @@ EX void gainItem(eItem it) {
|
|||||||
|
|
||||||
#define IF(x) if(g < (x) && g2 >= x && !peace::on)
|
#define IF(x) if(g < (x) && g2 >= x && !peace::on)
|
||||||
|
|
||||||
IF(R60/4)
|
if(in_full_game()) {
|
||||||
addMessage(XLAT("Collect treasure to access more different lands..."));
|
IF(R60/4)
|
||||||
IF(R30)
|
addMessage(XLAT("Collect treasure to access more different lands..."));
|
||||||
addMessage(XLAT("You feel that you have enough treasure to access new lands!"));
|
IF(R30)
|
||||||
IF(R30*3/2)
|
addMessage(XLAT("You feel that you have enough treasure to access new lands!"));
|
||||||
addMessage(XLAT("Collect more treasures, there are still more lands waiting..."));
|
IF(R30*3/2)
|
||||||
IF(R60)
|
addMessage(XLAT("Collect more treasures, there are still more lands waiting..."));
|
||||||
addMessage(XLAT("You feel that the stars are right, and you can access R'Lyeh!"));
|
IF(R60)
|
||||||
IF(R30*5/2)
|
addMessage(XLAT("You feel that the stars are right, and you can access R'Lyeh!"));
|
||||||
addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell..."));
|
IF(R30*5/2)
|
||||||
IF(R10 * 9)
|
addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell..."));
|
||||||
addMessage(XLAT("To access Hell, collect %1 treasures each of 9 kinds...", its(R10)));
|
IF(R10 * 9)
|
||||||
if(landUnlocked(laHell) && !lhu) {
|
addMessage(XLAT("To access Hell, collect %1 treasures each of 9 kinds...", its(R10)));
|
||||||
addMessage(XLAT("Abandon all hope, the gates of Hell are opened!"));
|
if(landUnlocked(laHell) && !lhu) {
|
||||||
addMessage(XLAT("And the Orbs of Yendor await!"));
|
addMessage(XLAT("Abandon all hope, the gates of Hell are opened!"));
|
||||||
|
addMessage(XLAT("And the Orbs of Yendor await!"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2430,8 +2430,10 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case laBrownian:
|
case laBrownian:
|
||||||
|
#if CAP_COMPLEX2
|
||||||
brownian::build(c, d);
|
brownian::build(c, d);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case laMirrored:
|
case laMirrored:
|
||||||
@ -2807,6 +2809,7 @@ EX void setdist(cell *c, int d, cell *from) {
|
|||||||
|
|
||||||
if(d >= BARLEV) {
|
if(d >= BARLEV) {
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
if(bt::in() && WDIM == 3 && !c->land && !sn::in()) {
|
if(bt::in() && WDIM == 3 && !c->land && !sn::in()) {
|
||||||
ld z = vid.binary_width;
|
ld z = vid.binary_width;
|
||||||
cell *cseek = c;
|
cell *cseek = c;
|
||||||
@ -2816,6 +2819,7 @@ EX void setdist(cell *c, int d, cell *from) {
|
|||||||
while(z < 3.999 && step < 10) cseek = cseek->cmove(bt::updir()), z *= scale;
|
while(z < 3.999 && step < 10) cseek = cseek->cmove(bt::updir()), z *= scale;
|
||||||
if(cseek->master->emeraldval) setland(c, eLand(cseek->master->emeraldval));
|
if(cseek->master->emeraldval) setland(c, eLand(cseek->master->emeraldval));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!c->land && from && (WDIM == 3 || !among(from->land, laBarrier, laElementalWall, laHauntedWall, laOceanWall)) && !quotient && !(chaosmode > 1)) {
|
if(!c->land && from && (WDIM == 3 || !among(from->land, laBarrier, laElementalWall, laHauntedWall, laOceanWall)) && !quotient && !(chaosmode > 1)) {
|
||||||
if(!hasbardir(c)) setland(c, from->land);
|
if(!hasbardir(c)) setland(c, from->land);
|
||||||
|
@ -62,8 +62,11 @@ struct fullnoun {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if !CAP_TRANS
|
#if !CAP_TRANS
|
||||||
#define NUMEXTRA 11
|
#if HDR
|
||||||
const char* natchars[NUMEXTRA] = {"°","é","á", "²", "½", "Θ", "δ", "π", "ϕ", "ᵈ", "∞"};
|
#define NUMEXTRA 12
|
||||||
|
extern const char* natchars[NUMEXTRA];
|
||||||
|
#endif
|
||||||
|
const char* natchars[NUMEXTRA] = {"°","é","á", "²", "½", "Θ", "δ", "π", "ϕ", "ᵈ", "∞", "⌫"};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CAP_TRANS
|
#if CAP_TRANS
|
||||||
|
@ -459,6 +459,7 @@ constexpr int FALL = 98;
|
|||||||
constexpr int NO_SPACE = 97;
|
constexpr int NO_SPACE = 97;
|
||||||
constexpr int TELEPORT = 96;
|
constexpr int TELEPORT = 96;
|
||||||
constexpr int JUMP = 95;
|
constexpr int JUMP = 95;
|
||||||
|
constexpr int STAY = 94;
|
||||||
|
|
||||||
namespace whirlwind { cell *jumpDestination(cell*); }
|
namespace whirlwind { cell *jumpDestination(cell*); }
|
||||||
|
|
||||||
|
@ -1095,8 +1095,8 @@ EX namespace mapeditor {
|
|||||||
displayButton(8, vid.yres-8-fs*2, XLAT("ESC = return to the game"), SDLK_ESCAPE, 0);
|
displayButton(8, vid.yres-8-fs*2, XLAT("ESC = return to the game"), SDLK_ESCAPE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EX unordered_set<cell*> affected;
|
EX set<cell*> affected;
|
||||||
EX unordered_set<int> affected_id;
|
EX set<int> affected_id;
|
||||||
|
|
||||||
EX void showMapEditor() {
|
EX void showMapEditor() {
|
||||||
cmode = sm::MAP;
|
cmode = sm::MAP;
|
||||||
@ -1276,6 +1276,7 @@ EX namespace mapeditor {
|
|||||||
void list_spill(cellwalker tgt, cellwalker src, manual_celllister& cl) {
|
void list_spill(cellwalker tgt, cellwalker src, manual_celllister& cl) {
|
||||||
spill_list.clear();
|
spill_list.clear();
|
||||||
spill_list.emplace_back(tgt, src);
|
spill_list.emplace_back(tgt, src);
|
||||||
|
if(painttype == 7) return;
|
||||||
int crad = 0, nextstepat = 0;
|
int crad = 0, nextstepat = 0;
|
||||||
for(int i=0; i<isize(spill_list); i++) {
|
for(int i=0; i<isize(spill_list); i++) {
|
||||||
if(i == nextstepat) {
|
if(i == nextstepat) {
|
||||||
|
27
models.cpp
27
models.cpp
@ -200,12 +200,15 @@ EX namespace models {
|
|||||||
if(GDIM == 2 && pm == mdEquivolume) return false;
|
if(GDIM == 2 && pm == mdEquivolume) return false;
|
||||||
if(GDIM == 3 && among(pm, mdBall, mdHyperboloid, mdFormula, mdPolygonal, mdRotatedHyperboles, mdSpiral, mdHemisphere)) return false;
|
if(GDIM == 3 && among(pm, mdBall, mdHyperboloid, mdFormula, mdPolygonal, mdRotatedHyperboles, mdSpiral, mdHemisphere)) return false;
|
||||||
if(pm == mdCentralInversion && !euclid) return false;
|
if(pm == mdCentralInversion && !euclid) return false;
|
||||||
|
if(pm == mdPoorMan) return hyperbolic;
|
||||||
|
if(pm == mdRetroHammer) return hyperbolic;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool has_orientation(eModel m) {
|
EX bool has_orientation(eModel m) {
|
||||||
if(m == mdHorocyclic)
|
if(m == mdHorocyclic)
|
||||||
return hyperbolic;
|
return hyperbolic;
|
||||||
|
if((m == mdPerspective || m == mdGeodesic) && panini_alpha) return true;
|
||||||
return
|
return
|
||||||
among(m, mdHalfplane, mdPolynomial, mdPolygonal, mdTwoPoint, mdJoukowsky, mdJoukowskyInverted, mdSpiral, mdSimulatedPerspective, mdTwoHybrid, mdHorocyclic, mdAxial, mdAntiAxial, mdQuadrant,
|
among(m, mdHalfplane, mdPolynomial, mdPolygonal, mdTwoPoint, mdJoukowsky, mdJoukowskyInverted, mdSpiral, mdSimulatedPerspective, mdTwoHybrid, mdHorocyclic, mdAxial, mdAntiAxial, mdQuadrant,
|
||||||
mdWerner, mdAitoff, mdHammer, mdLoximuthal, mdWinkelTripel) || mdBandAny();
|
mdWerner, mdAitoff, mdHammer, mdLoximuthal, mdWinkelTripel) || mdBandAny();
|
||||||
@ -442,7 +445,9 @@ EX namespace models {
|
|||||||
dialog::addBreak(50);
|
dialog::addBreak(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(among(vpmodel, mdDisk, mdBall, mdHyperboloid, mdRotatedHyperboles)) {
|
if(among(vpmodel, mdDisk, mdBall, mdHyperboloid, mdRotatedHyperboles, mdPanini)) {
|
||||||
|
dynamicval<eModel> v(vpconf.model, vpconf.model);
|
||||||
|
if(vpmodel == mdHyperboloid) vpconf.model = mdDisk;
|
||||||
dialog::addSelItem(XLAT("projection distance"), fts(vpconf.alpha) + " (" + current_proj_name() + ")", 'p');
|
dialog::addSelItem(XLAT("projection distance"), fts(vpconf.alpha) + " (" + current_proj_name() + ")", 'p');
|
||||||
dialog::add_action(projectionDialog);
|
dialog::add_action(projectionDialog);
|
||||||
}
|
}
|
||||||
@ -613,6 +618,10 @@ EX namespace models {
|
|||||||
dialog::scaleLog();
|
dialog::scaleLog();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vpmodel == mdHyperboloid) {
|
||||||
|
dialog::addBoolItem_action(XLAT("show flat"), pconf.show_hyperboloid_flat, 'b');
|
||||||
|
}
|
||||||
|
|
||||||
if(vpmodel == mdCollignon) {
|
if(vpmodel == mdCollignon) {
|
||||||
dialog::addSelItem(XLAT("parameter"), fts(vpconf.collignon_parameter) + (vpconf.collignon_reflected ? " (r)" : ""), 'b');
|
dialog::addSelItem(XLAT("parameter"), fts(vpconf.collignon_parameter) + (vpconf.collignon_reflected ? " (r)" : ""), 'b');
|
||||||
@ -636,13 +645,17 @@ EX namespace models {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vpmodel == mdLoximuthal) {
|
if(among(vpmodel, mdLoximuthal, mdRetroHammer, mdRetroCraig)) {
|
||||||
dialog::addSelItem(XLAT("parameter"), fts(vpconf.loximuthal_parameter), 'b');
|
dialog::addSelItem(XLAT("parameter"), fts(vpconf.loximuthal_parameter), 'b');
|
||||||
dialog::add_action([](){
|
dialog::add_action([vpmodel](){
|
||||||
dialog::editNumber(vpconf.loximuthal_parameter, -M_PI/2, M_PI/2, .1, 0, XLAT("parameter"),
|
dialog::editNumber(vpconf.loximuthal_parameter, -M_PI/2, M_PI/2, .1, 0, XLAT("parameter"),
|
||||||
|
(vpmodel == mdLoximuthal ?
|
||||||
"This model is similar to azimuthal equidistant, but based on loxodromes (lines of constant geographic direction) rather than geodesics. "
|
"This model is similar to azimuthal equidistant, but based on loxodromes (lines of constant geographic direction) rather than geodesics. "
|
||||||
"The loximuthal projection maps (the shortest) loxodromes to straight lines of the same length, going through the starting point. "
|
"The loximuthal projection maps (the shortest) loxodromes to straight lines of the same length, going through the starting point. "
|
||||||
"This setting changes the latitude of the starting point."
|
"This setting changes the latitude of the starting point." :
|
||||||
|
"In retroazimuthal projections, a point is drawn at such a point that the azimuth *from* that point to the chosen central point is correct. "
|
||||||
|
"For example, if you should move east, the point is drawn to the right. This parameter is the latitude of the central point.")
|
||||||
|
+ string(hyperbolic ? "\n\n(In hyperbolic geometry directions are assigned according to the Lobachevsky coordinates.)" : "")
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -827,7 +840,7 @@ EX namespace models {
|
|||||||
PHASEFROM(2);
|
PHASEFROM(2);
|
||||||
if(pmodel == mdCollignon) shift_arg_formula(vpconf.collignon_parameter);
|
if(pmodel == mdCollignon) shift_arg_formula(vpconf.collignon_parameter);
|
||||||
else if(pmodel == mdMiller) shift_arg_formula(vpconf.miller_parameter);
|
else if(pmodel == mdMiller) shift_arg_formula(vpconf.miller_parameter);
|
||||||
else if(pmodel == mdLoximuthal) shift_arg_formula(vpconf.loximuthal_parameter);
|
else if(among(pmodel, mdLoximuthal, mdRetroCraig, mdRetroHammer)) shift_arg_formula(vpconf.loximuthal_parameter);
|
||||||
else if(among(pmodel, mdAitoff, mdHammer, mdWinkelTripel)) shift_arg_formula(vpconf.aitoff_parameter);
|
else if(among(pmodel, mdAitoff, mdHammer, mdWinkelTripel)) shift_arg_formula(vpconf.aitoff_parameter);
|
||||||
if(pmodel == mdWinkelTripel) shift_arg_formula(vpconf.winkel_parameter);
|
if(pmodel == mdWinkelTripel) shift_arg_formula(vpconf.winkel_parameter);
|
||||||
}
|
}
|
||||||
@ -856,6 +869,10 @@ EX namespace models {
|
|||||||
PHASEFROM(2);
|
PHASEFROM(2);
|
||||||
shift_arg_formula(vpconf.skiprope);
|
shift_arg_formula(vpconf.skiprope);
|
||||||
}
|
}
|
||||||
|
else if(argis("-palpha")) {
|
||||||
|
PHASEFROM(2);
|
||||||
|
shift_arg_formula(panini_alpha, reset_all_shaders);
|
||||||
|
}
|
||||||
else if(argis("-zoom")) {
|
else if(argis("-zoom")) {
|
||||||
PHASEFROM(2); shift_arg_formula(vpconf.scale);
|
PHASEFROM(2); shift_arg_formula(vpconf.scale);
|
||||||
}
|
}
|
||||||
|
@ -318,10 +318,12 @@ EX eItem wanderingTreasure(cell *c) {
|
|||||||
|
|
||||||
/** generate the wandering monsters */
|
/** generate the wandering monsters */
|
||||||
EX void wandering() {
|
EX void wandering() {
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(mine::in_minesweeper()) {
|
if(mine::in_minesweeper()) {
|
||||||
mine::count_status();
|
mine::count_status();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(!canmove) return;
|
if(!canmove) return;
|
||||||
if(!gen_wandering) return;
|
if(!gen_wandering) return;
|
||||||
if(racing::on) return;
|
if(racing::on) return;
|
||||||
|
@ -108,6 +108,8 @@ EX void moveMonster(const movei& mi) {
|
|||||||
auto& cf = mi.s;
|
auto& cf = mi.s;
|
||||||
auto& ct = mi.t;
|
auto& ct = mi.t;
|
||||||
eMonster m = cf->monst;
|
eMonster m = cf->monst;
|
||||||
|
changes.ccell(cf);
|
||||||
|
changes.ccell(ct);
|
||||||
bool fri = isFriendly(cf);
|
bool fri = isFriendly(cf);
|
||||||
if(isDragon(m)) {
|
if(isDragon(m)) {
|
||||||
printf("called for Dragon\n");
|
printf("called for Dragon\n");
|
||||||
@ -117,6 +119,7 @@ EX void moveMonster(const movei& mi) {
|
|||||||
// the following line is necessary because otherwise plates disappear only inside the sight range
|
// the following line is necessary because otherwise plates disappear only inside the sight range
|
||||||
if(cellUnstable(cf) && !ignoresPlates(m)) {
|
if(cellUnstable(cf) && !ignoresPlates(m)) {
|
||||||
fallingFloorAnimation(cf);
|
fallingFloorAnimation(cf);
|
||||||
|
changes.ccell(cf);
|
||||||
cf->wall = waChasm;
|
cf->wall = waChasm;
|
||||||
}
|
}
|
||||||
moveEffect(mi, m);
|
moveEffect(mi, m);
|
||||||
@ -124,6 +127,7 @@ EX void moveMonster(const movei& mi) {
|
|||||||
(m == moShark || m == moCShark || m == moGreaterShark))
|
(m == moShark || m == moCShark || m == moGreaterShark))
|
||||||
achievement_gain_once("MOATSHARK");
|
achievement_gain_once("MOATSHARK");
|
||||||
if(m == moTentacleGhost) {
|
if(m == moTentacleGhost) {
|
||||||
|
changes.ccell(cf);
|
||||||
cf->monst = moTentacletail;
|
cf->monst = moTentacletail;
|
||||||
m = moGhost;
|
m = moGhost;
|
||||||
}
|
}
|
||||||
@ -156,10 +160,11 @@ EX void moveMonster(const movei& mi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fri || isBug(m) || items[itOrbDiscord]) stabbingAttack(cf, ct, m);
|
if(fri || isBug(m) || items[itOrbDiscord]) stabbingAttack(mi, m);
|
||||||
|
|
||||||
if(mi.d == JUMP && m == moVaulter) {
|
if(mi.d == JUMP && m == moVaulter) {
|
||||||
cell *cm = common_neighbor(cf, ct);
|
cell *cm = common_neighbor(cf, ct);
|
||||||
|
changes.ccell(cm);
|
||||||
if(cm->wall == waShrub) cm->wall = waNone;
|
if(cm->wall == waShrub) cm->wall = waNone;
|
||||||
if(cm->wall == waSmallTree) cm->wall = waNone;
|
if(cm->wall == waSmallTree) cm->wall = waNone;
|
||||||
if(cm->wall == waBigTree) cm->wall = waSmallTree;
|
if(cm->wall == waBigTree) cm->wall = waSmallTree;
|
||||||
@ -1518,7 +1523,10 @@ EX int stayvalue(eMonster m, cell *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** for an ally m at c, evaluate moving to c2 */
|
/** for an ally m at c, evaluate moving to c2 */
|
||||||
EX int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
|
EX int movevalue(eMonster m, cell *c, int dir, flagtype flags) {
|
||||||
|
|
||||||
|
auto mi = movei(c, dir);
|
||||||
|
auto& c2 = mi.t;
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
|
||||||
if(isPlayerOn(c2)) val = -3000;
|
if(isPlayerOn(c2)) val = -3000;
|
||||||
@ -1537,7 +1545,6 @@ EX int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
|
|||||||
isInactiveEnemy(c2,m) ? 1000 :
|
isInactiveEnemy(c2,m) ? 1000 :
|
||||||
-500;
|
-500;
|
||||||
|
|
||||||
else if(monstersnear(c2, m, NULL, c)) val = 50; // linked with mouse suicide!
|
|
||||||
else if(passable_for(m, c2, c, 0)) {
|
else if(passable_for(m, c2, c, 0)) {
|
||||||
#if CAP_COMPLEX2
|
#if CAP_COMPLEX2
|
||||||
if(mine::marked_mine(c2) && !ignoresPlates(m))
|
if(mine::marked_mine(c2) && !ignoresPlates(m))
|
||||||
@ -1545,12 +1552,22 @@ EX int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
val = 4000;
|
val = 4000;
|
||||||
|
|
||||||
|
int tk = tkills();
|
||||||
|
changes.init(true);
|
||||||
|
moveMonster(mi);
|
||||||
|
int tk2 = tkills();
|
||||||
|
bool b = monstersnear(mi.t, m);
|
||||||
|
changes.rollback();
|
||||||
|
if(b) val = 50;
|
||||||
|
else if(tk2 > tk) val += 1000 + 200 * (tk2 - tk);
|
||||||
}
|
}
|
||||||
else if(passable_for(m, c2, c, P_DEADLY)) val = -1100;
|
else if(passable_for(m, c2, c, P_DEADLY)) val = -1100;
|
||||||
else val = -1750;
|
else val = -1750;
|
||||||
|
|
||||||
if(c->monst == moGolem )
|
if(c->monst == moGolem ) {
|
||||||
val -= c2->cpdist;
|
val -= c2->pathdist;
|
||||||
|
}
|
||||||
else if(c->monst == moFriendlyGhost )
|
else if(c->monst == moFriendlyGhost )
|
||||||
val += c2->cpdist - 40;
|
val += c2->cpdist - 40;
|
||||||
else if(c->monst == moMouse) {
|
else if(c->monst == moMouse) {
|
||||||
@ -1599,9 +1616,9 @@ EX int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
|
|||||||
val -= 5;
|
val -= 5;
|
||||||
}
|
}
|
||||||
if(c->monst == moTameBomberbird) {
|
if(c->monst == moTameBomberbird) {
|
||||||
int d = c2->cpdist;
|
int d = c2->pathdist;
|
||||||
if(d == 1 && c->cpdist > 1) d = 5;
|
if(d == 1 && c->pathdist > 1) d = 5;
|
||||||
if(d == 2 && c->cpdist > 2) d = 4;
|
if(d == 2 && c->pathdist > 2) d = 4;
|
||||||
val -= d;
|
val -= d;
|
||||||
}
|
}
|
||||||
if(c->monst == moKnight && (eubinary || c2->master->alt)) {
|
if(c->monst == moKnight && (eubinary || c2->master->alt)) {
|
||||||
@ -1616,11 +1633,11 @@ EX int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
|
|||||||
EX void movegolems(flagtype flags) {
|
EX void movegolems(flagtype flags) {
|
||||||
if(items[itOrbEmpathy] && items[itOrbSlaying])
|
if(items[itOrbEmpathy] && items[itOrbSlaying])
|
||||||
flags |= AF_CRUSH;
|
flags |= AF_CRUSH;
|
||||||
pathdata pd(moMouse);
|
|
||||||
int qg = 0;
|
int qg = 0;
|
||||||
for(int i=0; i<isize(golems); i++) {
|
for(int i=0; i<isize(golems); i++) {
|
||||||
cell *c = golems[i];
|
cell *c = golems[i];
|
||||||
eMonster m = c->monst;
|
eMonster m = c->monst;
|
||||||
|
pathdata pd(m, false);
|
||||||
if(c->stuntime) continue;
|
if(c->stuntime) continue;
|
||||||
if(m == moGolem || m == moKnight || m == moTameBomberbird || m == moPrincess ||
|
if(m == moGolem || m == moKnight || m == moTameBomberbird || m == moPrincess ||
|
||||||
m == moPrincessArmed || m == moMouse || m == moFriendlyGhost) {
|
m == moPrincessArmed || m == moMouse || m == moFriendlyGhost) {
|
||||||
@ -1636,8 +1653,7 @@ EX void movegolems(flagtype flags) {
|
|||||||
|
|
||||||
DEBB(DF_TURN, ("moveval"));
|
DEBB(DF_TURN, ("moveval"));
|
||||||
for(int k=0; k<c->type; k++) if(c->move(k)) {
|
for(int k=0; k<c->type; k++) if(c->move(k)) {
|
||||||
cell *c2 = c->move(k);
|
int val = movevalue(m, c, k, flags);
|
||||||
int val = movevalue(m, c, c2, flags);
|
|
||||||
|
|
||||||
if(val > bestv) bestv = val, bdirs.clear();
|
if(val > bestv) bestv = val, bdirs.clear();
|
||||||
if(val == bestv) bdirs.push_back(k);
|
if(val == bestv) bdirs.push_back(k);
|
||||||
@ -1646,7 +1662,7 @@ EX void movegolems(flagtype flags) {
|
|||||||
if(m == moTameBomberbird) {
|
if(m == moTameBomberbird) {
|
||||||
cell *c2 = whirlwind::jumpDestination(c);
|
cell *c2 = whirlwind::jumpDestination(c);
|
||||||
if(c2 && !c2->monst) {
|
if(c2 && !c2->monst) {
|
||||||
int val = movevalue(m, c, c2, flags);
|
int val = movevalue(m, c, STRONGWIND, flags);
|
||||||
// printf("val = %d bestv = %d\n",
|
// printf("val = %d bestv = %d\n",
|
||||||
if(val > bestv) bestv = val, bdirs.clear();
|
if(val > bestv) bestv = val, bdirs.clear();
|
||||||
if(val == bestv) bdirs.push_back(STRONGWIND);
|
if(val == bestv) bdirs.push_back(STRONGWIND);
|
||||||
|
49
multi.cpp
49
multi.cpp
@ -221,22 +221,15 @@ struct key_configurer {
|
|||||||
|
|
||||||
int sc;
|
int sc;
|
||||||
vector<string>& shmupcmdtable;
|
vector<string>& shmupcmdtable;
|
||||||
|
string caption;
|
||||||
int setwhat;
|
int setwhat;
|
||||||
|
|
||||||
key_configurer(int sc, vector<string>& sct) : sc(sc), shmupcmdtable(sct), setwhat(0) {}
|
key_configurer(int sc, vector<string>& sct, const string& caption) : sc(sc), shmupcmdtable(sct), caption(caption), setwhat(0) {
|
||||||
|
}
|
||||||
|
|
||||||
void operator() () {
|
void operator() () {
|
||||||
|
|
||||||
dialog::init(
|
dialog::init(caption);
|
||||||
XLAT(sc == 1 ? "configure player 1" :
|
|
||||||
sc == 2 ? "configure player 2" :
|
|
||||||
sc == 3 ? "configure panning" :
|
|
||||||
sc == 4 ? "configure player 3" :
|
|
||||||
sc == 5 ? "configure player 4" :
|
|
||||||
sc == 6 ? "configure player 5" :
|
|
||||||
sc == 7 ? "configure player 6" :
|
|
||||||
sc == 8 ? "configure player 7" : ""
|
|
||||||
));
|
|
||||||
|
|
||||||
getcstat = ' ';
|
getcstat = ' ';
|
||||||
|
|
||||||
@ -302,7 +295,21 @@ struct key_configurer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EX reaction_t get_key_configurer(int sc, vector<string>& sct) { return key_configurer(sc, sct); }
|
EX reaction_t get_key_configurer(int sc, vector<string>& sct, string caption) {
|
||||||
|
return key_configurer(sc, sct, caption);
|
||||||
|
}
|
||||||
|
|
||||||
|
EX reaction_t get_key_configurer(int sc, vector<string>& sct) {
|
||||||
|
return key_configurer(sc, sct, XLAT(sc == 1 ? "configure player 1" :
|
||||||
|
sc == 2 ? "configure player 2" :
|
||||||
|
sc == 3 ? "configure panning" :
|
||||||
|
sc == 4 ? "configure player 3" :
|
||||||
|
sc == 5 ? "configure player 4" :
|
||||||
|
sc == 6 ? "configure player 5" :
|
||||||
|
sc == 7 ? "configure player 6" :
|
||||||
|
sc == 8 ? "configure player 7" : ""
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#if CAP_SDLJOY
|
#if CAP_SDLJOY
|
||||||
struct joy_configurer {
|
struct joy_configurer {
|
||||||
@ -456,14 +463,14 @@ struct shmup_configurer {
|
|||||||
|
|
||||||
if(0) ;
|
if(0) ;
|
||||||
#if CAP_SDL
|
#if CAP_SDL
|
||||||
else if(uni == '1') pushScreen(key_configurer(1, cmdlist));
|
else if(uni == '1') pushScreen(get_key_configurer(1, cmdlist));
|
||||||
else if(uni == '2') pushScreen(key_configurer(2, cmdlist));
|
else if(uni == '2') pushScreen(get_key_configurer(2, cmdlist));
|
||||||
else if(uni == 'p') pushScreen(key_configurer(3, GDIM == 3 ? pancmds3 : pancmds));
|
else if(uni == 'p') pushScreen(get_key_configurer(3, GDIM == 3 ? pancmds3 : pancmds));
|
||||||
else if(uni == '3') pushScreen(key_configurer(4, cmdlist));
|
else if(uni == '3') pushScreen(get_key_configurer(4, cmdlist));
|
||||||
else if(uni == '4') pushScreen(key_configurer(5, cmdlist));
|
else if(uni == '4') pushScreen(get_key_configurer(5, cmdlist));
|
||||||
else if(uni == '5') pushScreen(key_configurer(6, cmdlist));
|
else if(uni == '5') pushScreen(get_key_configurer(6, cmdlist));
|
||||||
else if(uni == '6') pushScreen(key_configurer(7, cmdlist));
|
else if(uni == '6') pushScreen(get_key_configurer(7, cmdlist));
|
||||||
else if(uni == '7') pushScreen(key_configurer(8, cmdlist));
|
else if(uni == '7') pushScreen(get_key_configurer(8, cmdlist));
|
||||||
#if CAP_SDLJOY
|
#if CAP_SDLJOY
|
||||||
else if(uni == 'j') pushScreen(joy_configurer(players));
|
else if(uni == 'j') pushScreen(joy_configurer(players));
|
||||||
#endif
|
#endif
|
||||||
@ -638,6 +645,7 @@ EX void initConfig() {
|
|||||||
multi::scs[5].uicolor = 0x00C0C0FF;
|
multi::scs[5].uicolor = 0x00C0C0FF;
|
||||||
multi::scs[6].uicolor = 0xC0C0C0FF;
|
multi::scs[6].uicolor = 0xC0C0C0FF;
|
||||||
|
|
||||||
|
#if CAP_CONFIG
|
||||||
addsaver(multi::players, "mode-number of players");
|
addsaver(multi::players, "mode-number of players");
|
||||||
addsaver(alwaysuse, "use configured keys");
|
addsaver(alwaysuse, "use configured keys");
|
||||||
// unfortunately we cannot use key names here because SDL is not yet initialized
|
// unfortunately we cannot use key names here because SDL is not yet initialized
|
||||||
@ -656,6 +664,7 @@ EX void initConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int i=0; i<7; i++) addsaver(multi::scs[i], "player"+its(i));
|
for(int i=0; i<7; i++) addsaver(multi::scs[i], "player"+its(i));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void handleInput(int delta) {
|
EX void handleInput(int delta) {
|
||||||
|
@ -295,11 +295,17 @@ EX namespace dual {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
variation = eVariation::pure;
|
variation = eVariation::pure;
|
||||||
|
#if CAP_ARCM
|
||||||
geometry = s == 0 ? gEuclidSquare : gArchimedean;
|
geometry = s == 0 ? gEuclidSquare : gArchimedean;
|
||||||
|
#else
|
||||||
|
geometry = gEuclidSquare;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
firstland = specialland = laCrossroads4;
|
firstland = specialland = laCrossroads4;
|
||||||
|
#if CAP_ARCM
|
||||||
if(geometry == gArchimedean)
|
if(geometry == gArchimedean)
|
||||||
arcm::current.parse("4,4,4,4,4");
|
arcm::current.parse("4,4,4,4,4");
|
||||||
|
#endif
|
||||||
check_cgi();
|
check_cgi();
|
||||||
cgi.require_basics();
|
cgi.require_basics();
|
||||||
dgd[s].storegame();
|
dgd[s].storegame();
|
||||||
|
19
mymake.cpp
19
mymake.cpp
@ -60,6 +60,19 @@ void set_mingw64() {
|
|||||||
setvbuf(stdout, NULL, _IONBF, 0); // MinGW is quirky with output buffering
|
setvbuf(stdout, NULL, _IONBF, 0); // MinGW is quirky with output buffering
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_web() {
|
||||||
|
preprocessor = "/usr/lib/emscripten/em++ -E";
|
||||||
|
compiler = "/usr/lib/emscripten/em++ -c";
|
||||||
|
default_standard = standard = " -std=c++17";
|
||||||
|
opts = "-DISWEB=1";
|
||||||
|
linker =
|
||||||
|
"/usr/lib/emscripten/em++ -s USE_ZLIB=1 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0 -s TOTAL_MEMORY=512MB "
|
||||||
|
"-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"FS\",\"ccall\"]' "
|
||||||
|
"-s EXPORTED_FUNCTIONS=\"['_main', '_use_file']\" "
|
||||||
|
"-s DISABLE_EXCEPTION_CATCHING=0 -o mhyper.html";
|
||||||
|
libs = "";
|
||||||
|
}
|
||||||
|
|
||||||
vector<string> modules;
|
vector<string> modules;
|
||||||
|
|
||||||
time_t get_file_time(const string s) {
|
time_t get_file_time(const string s) {
|
||||||
@ -123,6 +136,12 @@ int main(int argc, char **argv) {
|
|||||||
obj_dir += "/linux";
|
obj_dir += "/linux";
|
||||||
setdir += "../";
|
setdir += "../";
|
||||||
}
|
}
|
||||||
|
else if(s == "-web") {
|
||||||
|
set_web();
|
||||||
|
modules.push_back("hyperweb");
|
||||||
|
obj_dir += "/web";
|
||||||
|
setdir += "../";
|
||||||
|
}
|
||||||
else if(s.substr(0, 2) == "-f") {
|
else if(s.substr(0, 2) == "-f") {
|
||||||
opts += " " + s;
|
opts += " " + s;
|
||||||
obj_dir += "/";
|
obj_dir += "/";
|
||||||
|
@ -127,11 +127,11 @@ unsigned char fonttable[] = {
|
|||||||
|
|
||||||
unsigned char *ftv = fonttable;
|
unsigned char *ftv = fonttable;
|
||||||
|
|
||||||
void resetTabFont() {
|
EX void resetTabFont() {
|
||||||
ftv = fonttable;
|
ftv = fonttable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadCompressedChar(int &otwidth, int &otheight, unsigned char *tpix) {
|
EX void loadCompressedChar(int &otwidth, int &otheight, unsigned char *tpix) {
|
||||||
if(*ftv == 255) {
|
if(*ftv == 255) {
|
||||||
fprintf(stderr, "There is something wrong with the font table\n");
|
fprintf(stderr, "There is something wrong with the font table\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -236,8 +236,8 @@ EX namespace sn {
|
|||||||
struct hrmap_solnih : hrmap {
|
struct hrmap_solnih : hrmap {
|
||||||
hrmap *binary_map;
|
hrmap *binary_map;
|
||||||
hrmap *ternary_map; /* nih only */
|
hrmap *ternary_map; /* nih only */
|
||||||
unordered_map<pair<heptagon*, heptagon*>, heptagon*> at;
|
map<pair<heptagon*, heptagon*>, heptagon*> at;
|
||||||
unordered_map<heptagon*, pair<heptagon*, heptagon*>> coords;
|
map<heptagon*, pair<heptagon*, heptagon*>> coords;
|
||||||
|
|
||||||
heptagon *origin;
|
heptagon *origin;
|
||||||
|
|
||||||
@ -872,8 +872,8 @@ EX namespace nilv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct hrmap_nil : hrmap {
|
struct hrmap_nil : hrmap {
|
||||||
unordered_map<mvec, heptagon*> at;
|
map<mvec, heptagon*> at;
|
||||||
unordered_map<heptagon*, mvec> coords;
|
map<heptagon*, mvec> coords;
|
||||||
|
|
||||||
heptagon *getOrigin() override { return get_at(mvec_zero); }
|
heptagon *getOrigin() override { return get_at(mvec_zero); }
|
||||||
|
|
||||||
@ -1231,6 +1231,8 @@ EX namespace hybrid {
|
|||||||
dynamicval<hrmap*> gpm(pmap, this);
|
dynamicval<hrmap*> gpm(pmap, this);
|
||||||
dynamicval<eGeometry> gag(actual_geometry, geometry);
|
dynamicval<eGeometry> gag(actual_geometry, geometry);
|
||||||
dynamicval<eGeometry> g(geometry, underlying);
|
dynamicval<eGeometry> g(geometry, underlying);
|
||||||
|
dynamicval<int> gss(underlying_cgip->single_step, cgi.single_step);
|
||||||
|
dynamicval<int> gsp(underlying_cgip->psl_steps, cgi.psl_steps);
|
||||||
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
|
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
|
||||||
dynamicval<hrmap*> gu(currentmap, underlying_map);
|
dynamicval<hrmap*> gu(currentmap, underlying_map);
|
||||||
return t();
|
return t();
|
||||||
@ -1308,6 +1310,8 @@ EX namespace hybrid {
|
|||||||
if(!hybri) return f();
|
if(!hybri) return f();
|
||||||
dynamicval<eGeometry> g(geometry, underlying);
|
dynamicval<eGeometry> g(geometry, underlying);
|
||||||
dynamicval<eGeometry> gag(actual_geometry, geometry);
|
dynamicval<eGeometry> gag(actual_geometry, geometry);
|
||||||
|
dynamicval<int> gss(underlying_cgip->single_step, cgi.single_step);
|
||||||
|
dynamicval<int> gsp(underlying_cgip->psl_steps, cgi.psl_steps);
|
||||||
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
|
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
|
||||||
dynamicval<hrmap*> gpm(pmap, currentmap);
|
dynamicval<hrmap*> gpm(pmap, currentmap);
|
||||||
dynamicval<hrmap*> gm(currentmap, get_umap());
|
dynamicval<hrmap*> gm(currentmap, get_umap());
|
||||||
@ -1345,13 +1349,17 @@ EX namespace hybrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX int wall_offset(cell *c) {
|
EX int wall_offset(cell *c) {
|
||||||
if(GOLDBERG) {
|
if(GOLDBERG || INVERSE) {
|
||||||
/* a bit slow... */
|
/* a bit slow... */
|
||||||
cell *c1 = WDIM == 2 ? c : get_where(c).first;
|
cell *c1 = WDIM == 2 ? c : get_where(c).first;
|
||||||
gp::draw_li = WDIM == 2 ? gp::get_local_info(c1) : PIU(gp::get_local_info(c1));
|
gp::draw_li = WDIM == 2 ? gp::get_local_info(c1) : PIU(gp::get_local_info(c1));
|
||||||
}
|
}
|
||||||
auto ugeometry = hybri ? hybrid::underlying : geometry;
|
auto ugeometry = hybri ? hybrid::underlying : geometry;
|
||||||
|
#if CAP_ARCM
|
||||||
int id = ugeometry == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
|
int id = ugeometry == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
|
||||||
|
#else
|
||||||
|
int id = shvid(c);
|
||||||
|
#endif
|
||||||
if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, {-1, nullptr});
|
if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, {-1, nullptr});
|
||||||
auto &wop = cgi.walloffsets[id];
|
auto &wop = cgi.walloffsets[id];
|
||||||
int &wo = wop.first;
|
int &wo = wop.first;
|
||||||
@ -2057,14 +2065,19 @@ EX namespace rots {
|
|||||||
return spin(beta) * uxpush(distance/2) * spin(-beta+alpha);
|
return spin(beta) * uxpush(distance/2) * spin(-beta+alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<int, transmatrix> saved_matrices_ray;
|
std::map<int, transmatrix> saved_matrices_ray;
|
||||||
|
|
||||||
EX transmatrix ray_iadj(cell *c1, int i) {
|
EX transmatrix ray_iadj(cell *c1, int i) {
|
||||||
if(i == c1->type-1) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
|
if(i == c1->type-1) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
|
||||||
if(i == c1->type-2) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
|
if(i == c1->type-2) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
|
||||||
cell *c2 = c1->cmove(i);
|
cell *c2 = c1->cmove(i);
|
||||||
|
#if CAP_ARCM
|
||||||
int id1 = hybrid::underlying == gArchimedean ? arcm::id_of(c1->master) + 20 * arcm::parent_index_of(c1->master) : shvid(c1);
|
int id1 = hybrid::underlying == gArchimedean ? arcm::id_of(c1->master) + 20 * arcm::parent_index_of(c1->master) : shvid(c1);
|
||||||
int id2 = hybrid::underlying == gArchimedean ? arcm::id_of(c2->master) + 20 * arcm::parent_index_of(c2->master) : shvid(c2);
|
int id2 = hybrid::underlying == gArchimedean ? arcm::id_of(c2->master) + 20 * arcm::parent_index_of(c2->master) : shvid(c2);
|
||||||
|
#else
|
||||||
|
int id1 = shvid(c1);
|
||||||
|
int id2 = shvid(c2);
|
||||||
|
#endif
|
||||||
int j = c1->c.spin(i);
|
int j = c1->c.spin(i);
|
||||||
int id = id1 + (id2 << 10) + (i << 20) + (j << 26);
|
int id = id1 + (id2 << 10) + (i << 20) + (j << 26);
|
||||||
auto &M = saved_matrices_ray[id];
|
auto &M = saved_matrices_ray[id];
|
||||||
@ -2084,14 +2097,19 @@ EX namespace rots {
|
|||||||
|
|
||||||
struct hrmap_rotation_space : hybrid::hrmap_hybrid {
|
struct hrmap_rotation_space : hybrid::hrmap_hybrid {
|
||||||
|
|
||||||
std::unordered_map<int, transmatrix> saved_matrices;
|
std::map<int, transmatrix> saved_matrices;
|
||||||
|
|
||||||
transmatrix adj(cell *c1, int i) override {
|
transmatrix adj(cell *c1, int i) override {
|
||||||
if(i == c1->type-2) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
|
if(i == c1->type-2) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
|
||||||
if(i == c1->type-1) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
|
if(i == c1->type-1) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
|
||||||
cell *c2 = c1->cmove(i);
|
cell *c2 = c1->cmove(i);
|
||||||
|
#if CAP_ARCM
|
||||||
int id1 = hybrid::underlying == gArchimedean ? arcm::id_of(c1->master) + 20 * arcm::parent_index_of(c1->master) : shvid(c1);
|
int id1 = hybrid::underlying == gArchimedean ? arcm::id_of(c1->master) + 20 * arcm::parent_index_of(c1->master) : shvid(c1);
|
||||||
int id2 = hybrid::underlying == gArchimedean ? arcm::id_of(c2->master) + 20 * arcm::parent_index_of(c2->master) : shvid(c2);
|
int id2 = hybrid::underlying == gArchimedean ? arcm::id_of(c2->master) + 20 * arcm::parent_index_of(c2->master) : shvid(c2);
|
||||||
|
#else
|
||||||
|
int id1 = shvid(c1);
|
||||||
|
int id2 = shvid(c2);
|
||||||
|
#endif
|
||||||
int j = c1->c.spin(i);
|
int j = c1->c.spin(i);
|
||||||
int id = id1 + (id2 << 10) + (i << 20) + (j << 26);
|
int id = id1 + (id2 << 10) + (i << 20) + (j << 26);
|
||||||
auto &M = saved_matrices[id];
|
auto &M = saved_matrices[id];
|
||||||
|
@ -309,7 +309,7 @@ EX eOrbLandRelation getOLR(eItem it, eLand l) {
|
|||||||
return olrUseless;
|
return olrUseless;
|
||||||
|
|
||||||
if(l == laPrincessQuest)
|
if(l == laPrincessQuest)
|
||||||
if(among(it, itOrbAether, itOrbFlash, itOrbTeleport, itOrbSummon, itOrbFreedom, itOrbFriend, itOrbPhasing))
|
if(among(it, itOrbAether, itOrbFlash, itOrbTeleport, itOrbSummon, itOrbFreedom, itOrbFriend, itOrbPhasing, itOrbChaos))
|
||||||
return olrForbidden;
|
return olrForbidden;
|
||||||
|
|
||||||
if(l == laTemple)
|
if(l == laTemple)
|
||||||
|
27
orbs.cpp
27
orbs.cpp
@ -88,7 +88,9 @@ EX bool reduceOrbPower(eItem it, int cap) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(items[it] > cap && timerghost) items[it] = cap;
|
if(items[it] > cap && timerghost) items[it] = cap;
|
||||||
|
#if CAP_COMPLEX2
|
||||||
mine::auto_teleport_charges();
|
mine::auto_teleport_charges();
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,8 +567,8 @@ EX void teleportTo(cell *dest) {
|
|||||||
if(b) {
|
if(b) {
|
||||||
killFriendlyIvy();
|
killFriendlyIvy();
|
||||||
drainOrb(itOrbTeleport);
|
drainOrb(itOrbTeleport);
|
||||||
movecost(cwt.at, dest, 3);
|
movecost(cwt.at, dest, 3);
|
||||||
playerMoveEffects(cwt.at, dest);
|
playerMoveEffects(movei(cwt.at, dest, TELEPORT));
|
||||||
afterplayermoved();
|
afterplayermoved();
|
||||||
bfs();
|
bfs();
|
||||||
}
|
}
|
||||||
@ -578,7 +580,7 @@ EX void teleportTo(cell *dest) {
|
|||||||
killFriendlyIvy();
|
killFriendlyIvy();
|
||||||
cell *from = cwt.at;
|
cell *from = cwt.at;
|
||||||
movecost(from, dest, 1);
|
movecost(from, dest, 1);
|
||||||
playerMoveEffects(cwt.at, dest);
|
playerMoveEffects(movei(cwt.at, dest, TELEPORT));
|
||||||
current_display->which_copy = unshift(ggmatrix(dest));
|
current_display->which_copy = unshift(ggmatrix(dest));
|
||||||
cwt.at = dest; cwt.spin = hrand(dest->type); flipplayer = !!(hrand(2));
|
cwt.at = dest; cwt.spin = hrand(dest->type); flipplayer = !!(hrand(2));
|
||||||
drainOrb(itOrbTeleport);
|
drainOrb(itOrbTeleport);
|
||||||
@ -596,7 +598,9 @@ EX void teleportTo(cell *dest) {
|
|||||||
checkmoveO();
|
checkmoveO();
|
||||||
|
|
||||||
movecost(from, dest, 2);
|
movecost(from, dest, 2);
|
||||||
|
#if CAP_COMPLEX2
|
||||||
mine::auto_teleport_charges();
|
mine::auto_teleport_charges();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {
|
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {
|
||||||
@ -634,8 +638,9 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons
|
|||||||
}
|
}
|
||||||
|
|
||||||
sword::reset();
|
sword::reset();
|
||||||
stabbingAttack(c1, dest, moPlayer, bonuskill);
|
auto mi = movei(c1, dest, JUMP);
|
||||||
playerMoveEffects(c1, dest);
|
stabbingAttack(mi, moPlayer, bonuskill);
|
||||||
|
playerMoveEffects(mi);
|
||||||
|
|
||||||
if(itemclass(byWhat) == IC_ORB)
|
if(itemclass(byWhat) == IC_ORB)
|
||||||
apply_impact(dest);
|
apply_impact(dest);
|
||||||
@ -654,7 +659,7 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons
|
|||||||
|
|
||||||
mirror::destroyAll();
|
mirror::destroyAll();
|
||||||
|
|
||||||
if(monstersnearO(a, dest, moPlayer, NULL, c1)) {
|
if(monstersnearO(a, dest)) {
|
||||||
changes.rollback();
|
changes.rollback();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -935,7 +940,7 @@ bool gun_attack(orbAction a, cell *dest) {
|
|||||||
attackMonster(dest, AF_GUN, moNone);
|
attackMonster(dest, AF_GUN, moNone);
|
||||||
apply_impact(dest);
|
apply_impact(dest);
|
||||||
|
|
||||||
if(monstersnearO(a, cwt.at, moPlayer, NULL, cwt.at)) {
|
if(monstersnearO(a, cwt.at)) {
|
||||||
changes.rollback();
|
changes.rollback();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1064,13 +1069,13 @@ void useOrbOfDragon(cell *c) {
|
|||||||
checkmoveO();
|
checkmoveO();
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool monstersnearO(orbAction a, cell *c, eMonster who, cell *pushto, cell *comefrom) {
|
EX bool monstersnearO(orbAction a, cell *c) {
|
||||||
// printf("[a = %d] ", a);
|
// printf("[a = %d] ", a);
|
||||||
if(shmup::on) return false;
|
if(shmup::on) return false;
|
||||||
if(a == roCheck && multi::players > 1)
|
if(a == roCheck && multi::players > 1)
|
||||||
return true;
|
return true;
|
||||||
else if(a == roMultiCheck) return false;
|
else if(a == roMultiCheck) return false;
|
||||||
else return monstersnear(c, who, pushto, comefrom);
|
else return monstersnear(c, moPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool isCheck(orbAction a) { return a == roCheck || a == roMultiCheck; }
|
EX bool isCheck(orbAction a) { return a == roCheck || a == roMultiCheck; }
|
||||||
@ -1237,12 +1242,12 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
|
|
||||||
if(c->monst) {
|
if(c->monst) {
|
||||||
if(!canAttack(cf, moFriendlyIvy, c, c->monst, 0)) continue;
|
if(!canAttack(cf, moFriendlyIvy, c, c->monst, 0)) continue;
|
||||||
if(monstersnear(cwt.at, moPlayer, NULL, cwt.at)) continue;
|
if(monstersnear(cwt.at, moPlayer)) continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!passable(c, cf, P_ISPLAYER | P_MONSTER)) continue;
|
if(!passable(c, cf, P_ISPLAYER | P_MONSTER)) continue;
|
||||||
if(strictlyAgainstGravity(c, cf, false, MF_IVY)) continue;
|
if(strictlyAgainstGravity(c, cf, false, MF_IVY)) continue;
|
||||||
if(monstersnear(cwt.at, moPlayer, c, cwt.at)) continue;
|
if(monstersnear(cwt.at, moPlayer)) continue;
|
||||||
}
|
}
|
||||||
dirs.push_back(d);
|
dirs.push_back(d);
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ EX int fieldval_uniq(cell *c) {
|
|||||||
}
|
}
|
||||||
else if(euc::in(2)) {
|
else if(euc::in(2)) {
|
||||||
auto p = euc2_coordinates(c);
|
auto p = euc2_coordinates(c);
|
||||||
if(bounded) return p.first + (p.second << 16);
|
if(bounded) return p.first + p.second * (1 << 16);
|
||||||
return gmod(p.first - 22 * p.second, 3*127);
|
return gmod(p.first - 22 * p.second, 3*127);
|
||||||
}
|
}
|
||||||
else if(euc::in(3)) {
|
else if(euc::in(3)) {
|
||||||
@ -1682,11 +1682,13 @@ EX namespace patterns {
|
|||||||
ep.extra_params["ey"] = y;
|
ep.extra_params["ey"] = y;
|
||||||
if(S7 == 6) ep.extra_params["ez"] = -x-y;
|
if(S7 == 6) ep.extra_params["ez"] = -x-y;
|
||||||
}
|
}
|
||||||
|
#if CAP_CRYSTAL
|
||||||
if(cryst) {
|
if(cryst) {
|
||||||
crystal::ldcoord co = crystal::get_ldcoord(c);
|
crystal::ldcoord co = crystal::get_ldcoord(c);
|
||||||
for(int i=0; i<crystal::MAXDIM; i++)
|
for(int i=0; i<crystal::MAXDIM; i++)
|
||||||
ep.extra_params["x"+its(i)] = co[i];
|
ep.extra_params["x"+its(i)] = co[i];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(asonov::in()) {
|
if(asonov::in()) {
|
||||||
auto co = asonov::get_coord(c->master);
|
auto co = asonov::get_coord(c->master);
|
||||||
ep.extra_params["ax"] = szgmod(co[0], asonov::period_xy);
|
ep.extra_params["ax"] = szgmod(co[0], asonov::period_xy);
|
||||||
|
96
pcmove.cpp
96
pcmove.cpp
@ -357,8 +357,8 @@ bool pcmove::swing() {
|
|||||||
sideAttack(cwt.at, d, moPlayer, 0);
|
sideAttack(cwt.at, d, moPlayer, 0);
|
||||||
|
|
||||||
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK);
|
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK);
|
||||||
|
|
||||||
if(monstersnear(cwt.at, moPlayer, nullptr, cwt.at)) {
|
if(monstersnear_add_pmi(movei(cwt.at, STAY))) {
|
||||||
if(vmsg())
|
if(vmsg())
|
||||||
wouldkill("You would be killed by %the1!");
|
wouldkill("You would be killed by %the1!");
|
||||||
return false;
|
return false;
|
||||||
@ -510,6 +510,13 @@ struct changes_t {
|
|||||||
void at_rollback(reaction_t act) {
|
void at_rollback(reaction_t act) {
|
||||||
if(on) rollbacks.emplace_back(act);
|
if(on) rollbacks.emplace_back(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void push_push(cell *tgt) {
|
||||||
|
pushes.push_back(tgt);
|
||||||
|
auto v = [] { pushes.pop_back(); };
|
||||||
|
rollbacks.push_back(v);
|
||||||
|
commits.push_back(v);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -601,7 +608,7 @@ bool pcmove::actual_move() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items[itOrbDomination] > ORBBASE && isMountable(c2->monst) && !monstersnear2() && fmsMove) {
|
if(items[itOrbDomination] > ORBBASE && isMountable(c2->monst) && fmsMove) {
|
||||||
if(checkonly) { nextmovetype = lmMove; return true; }
|
if(checkonly) { nextmovetype = lmMove; return true; }
|
||||||
if(!isMountable(cwt.at->monst)) dragon::target = NULL;
|
if(!isMountable(cwt.at->monst)) dragon::target = NULL;
|
||||||
movecost(cwt.at, c2, 3);
|
movecost(cwt.at, c2, 3);
|
||||||
@ -629,6 +636,7 @@ bool pcmove::actual_move() {
|
|||||||
addMessage(XLAT("You push %the1.", c2->wall));
|
addMessage(XLAT("You push %the1.", c2->wall));
|
||||||
lastmovetype = lmPush; lastmove = cwt.at;
|
lastmovetype = lmPush; lastmove = cwt.at;
|
||||||
pushThumper(mip);
|
pushThumper(mip);
|
||||||
|
changes.push_push(mip.t);
|
||||||
return perform_actual_move();
|
return perform_actual_move();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,8 +654,6 @@ bool pcmove::actual_move() {
|
|||||||
|
|
||||||
if(!c2->monst && cwt.at->wall == waBoat && cwt.at->item != itOrbYendor && boatGoesThrough(c2) && markOrb(itOrbWater) && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) {
|
if(!c2->monst && cwt.at->wall == waBoat && cwt.at->item != itOrbYendor && boatGoesThrough(c2) && markOrb(itOrbWater) && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) {
|
||||||
|
|
||||||
if(havePushConflict(cwt.at, checkonly)) return false;
|
|
||||||
|
|
||||||
if(c2->item && !cwt.at->item) moveItem(c2, cwt.at, false), boatmove = true;
|
if(c2->item && !cwt.at->item) moveItem(c2, cwt.at, false), boatmove = true;
|
||||||
placeWater(c2, cwt.at);
|
placeWater(c2, cwt.at);
|
||||||
moveBoat(mi);
|
moveBoat(mi);
|
||||||
@ -663,7 +669,6 @@ bool pcmove::actual_move() {
|
|||||||
bool pcmove::boat_move() {
|
bool pcmove::boat_move() {
|
||||||
|
|
||||||
cell *& c2 = mi.t;
|
cell *& c2 = mi.t;
|
||||||
if(havePushConflict(cwt.at, checkonly)) return false;
|
|
||||||
|
|
||||||
if(againstWind(c2, cwt.at)) {
|
if(againstWind(c2, cwt.at)) {
|
||||||
if(vmsg()) addMessage(XLAT(airdist(c2) < 3 ? "The Air Elemental blows you away!" : "You cannot go against the wind!"));
|
if(vmsg()) addMessage(XLAT(airdist(c2) < 3 ? "The Air Elemental blows you away!" : "You cannot go against the wind!"));
|
||||||
@ -744,8 +749,6 @@ bool pcmove::after_escape() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(havePushConflict(cwt.at, checkonly)) return false;
|
|
||||||
|
|
||||||
changes.ccell(c2);
|
changes.ccell(c2);
|
||||||
changes.ccell(cwt.at);
|
changes.ccell(cwt.at);
|
||||||
|
|
||||||
@ -756,6 +759,7 @@ bool pcmove::after_escape() {
|
|||||||
nextmovetype = lmMove;
|
nextmovetype = lmMove;
|
||||||
addMessage(XLAT("You push %the1 behind you!", waBigStatue));
|
addMessage(XLAT("You push %the1 behind you!", waBigStatue));
|
||||||
animateMovement(mi.rev(), LAYER_BOAT);
|
animateMovement(mi.rev(), LAYER_BOAT);
|
||||||
|
changes.push_push(cwt.at);
|
||||||
return perform_actual_move();
|
return perform_actual_move();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +853,7 @@ bool pcmove::move_if_okay() {
|
|||||||
|
|
||||||
if(switchplace_prevent(cwt.at, c2, checkonly))
|
if(switchplace_prevent(cwt.at, c2, checkonly))
|
||||||
return false;
|
return false;
|
||||||
if(!checkonly && warningprotection_hit(do_we_stab_a_friend(cwt.at, c2, moPlayer)))
|
if(!checkonly && warningprotection_hit(do_we_stab_a_friend(mi, moPlayer)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nextmovetype = lmMove;
|
nextmovetype = lmMove;
|
||||||
@ -899,7 +903,7 @@ bool pcmove::attack() {
|
|||||||
|
|
||||||
if(!ca) {
|
if(!ca) {
|
||||||
if(forcedmovetype == fmAttack) {
|
if(forcedmovetype == fmAttack) {
|
||||||
if(monstersnear(cwt.at,moPlayer,NULL,cwt.at)) {
|
if(monstersnear_add_pmi(movei(cwt.at, STAY))) {
|
||||||
if(vmsg()) wouldkill("%The1 would get you!");
|
if(vmsg()) wouldkill("%The1 would get you!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -922,10 +926,9 @@ bool pcmove::attack() {
|
|||||||
else
|
else
|
||||||
mip.t = c2;
|
mip.t = c2;
|
||||||
if(mip.t) changes.ccell(mip.t);
|
if(mip.t) changes.ccell(mip.t);
|
||||||
|
changes.push_push(mip.t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(havePushConflict(mip.t, checkonly)) return false;
|
|
||||||
|
|
||||||
if(!(isWatery(cwt.at) && c2->monst == moWaterElemental) && checkNeedMove(checkonly, true))
|
if(!(isWatery(cwt.at) && c2->monst == moWaterElemental) && checkNeedMove(checkonly, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -982,7 +985,7 @@ bool pcmove::attack() {
|
|||||||
lastmovetype = lmAttack; lastmove = c2;
|
lastmovetype = lmAttack; lastmove = c2;
|
||||||
swordAttackStatic();
|
swordAttackStatic();
|
||||||
|
|
||||||
if(monstersnear(cwt.at, moPlayer, nullptr, cwt.at)) {
|
if(monstersnear_add_pmi(movei(cwt.at, STAY))) {
|
||||||
if(vmsg()) wouldkill("You would be killed by %the1!");
|
if(vmsg()) wouldkill("You would be killed by %the1!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1090,18 +1093,18 @@ bool pcmove::perform_move_or_jump() {
|
|||||||
lastmovetype = lmMove; lastmove = cwt.at;
|
lastmovetype = lmMove; lastmove = cwt.at;
|
||||||
apply_chaos();
|
apply_chaos();
|
||||||
|
|
||||||
stabbingAttack(cwt.at, mi.t, moPlayer);
|
stabbingAttack(mi, moPlayer);
|
||||||
cell *c1 = cwt.at;
|
|
||||||
changes.value_keep(cwt);
|
changes.value_keep(cwt);
|
||||||
cwt += wstep;
|
cwt += wstep;
|
||||||
|
|
||||||
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK | mirror::GO);
|
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK | mirror::GO);
|
||||||
|
|
||||||
playerMoveEffects(c1, mi.t);
|
auto pmi = player_move_info(mi);
|
||||||
|
playerMoveEffects(mi);
|
||||||
|
|
||||||
if(mi.t->monst == moFriendlyIvy) changes.ccell(mi.t), mi.t->monst = moNone;
|
if(mi.t->monst == moFriendlyIvy) changes.ccell(mi.t), mi.t->monst = moNone;
|
||||||
|
|
||||||
if(monstersnear(cwt.at, moPlayer, nullptr, c1)) {
|
if(monstersnear_add_pmi(pmi)) {
|
||||||
if(vmsg()) wouldkill("%The1 would kill you there!");
|
if(vmsg()) wouldkill("%The1 would kill you there!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1135,19 +1138,21 @@ bool pcmove::stay() {
|
|||||||
return false;
|
return false;
|
||||||
swordAttackStatic();
|
swordAttackStatic();
|
||||||
nextmovetype = lmSkip;
|
nextmovetype = lmSkip;
|
||||||
if(monstersnear(cwt.at, moPlayer, nullptr, cwt.at)) {
|
|
||||||
|
mi = movei(cwt.at, STAY);
|
||||||
|
if(last_gravity_state && !gravity_state)
|
||||||
|
playerMoveEffects(mi);
|
||||||
|
if(d == -2)
|
||||||
|
dropGreenStone(cwt.at);
|
||||||
|
|
||||||
|
if(monstersnear_add_pmi(mi)) {
|
||||||
if(vmsg()) wouldkill("%The1 would get you!");
|
if(vmsg()) wouldkill("%The1 would get you!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(checkonly) return true;
|
if(checkonly) return true;
|
||||||
if(changes.on) changes.commit();
|
if(changes.on) changes.commit();
|
||||||
if(d == -2)
|
|
||||||
dropGreenStone(cwt.at);
|
|
||||||
if(cellUnstable(cwt.at) && !markOrb(itOrbAether))
|
if(cellUnstable(cwt.at) && !markOrb(itOrbAether))
|
||||||
doesFallSound(cwt.at);
|
doesFallSound(cwt.at);
|
||||||
|
|
||||||
if(last_gravity_state && !gravity_state)
|
|
||||||
playerMoveEffects(cwt.at, cwt.at);
|
|
||||||
|
|
||||||
return after_move();
|
return after_move();
|
||||||
}
|
}
|
||||||
@ -1246,12 +1251,14 @@ EX bool playerInPower() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void playerMoveEffects(cell *c1, cell *c2) {
|
EX void playerMoveEffects(movei mi) {
|
||||||
|
cell *c1 = mi.s;
|
||||||
|
cell *c2 = mi.t;
|
||||||
|
|
||||||
if(peace::on) items[itOrbSword] = c2->land == laBurial ? 100 : 0;
|
if(peace::on) items[itOrbSword] = c2->land == laBurial ? 100 : 0;
|
||||||
|
|
||||||
changes.value_keep(sword::dir[multi::cpid]);
|
changes.value_keep(sword::dir[multi::cpid]);
|
||||||
sword::dir[multi::cpid] = sword::shift(c1, c2, sword::dir[multi::cpid]);
|
sword::dir[multi::cpid] = sword::shift(mi, sword::dir[multi::cpid]);
|
||||||
|
|
||||||
destroyWeakBranch(c1, c2, moPlayer);
|
destroyWeakBranch(c1, c2, moPlayer);
|
||||||
|
|
||||||
@ -1457,20 +1464,20 @@ EX void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EX eMonster do_we_stab_a_friend(cell *mf, cell *mt, eMonster who) {
|
EX eMonster do_we_stab_a_friend(movei mi, eMonster who) {
|
||||||
eMonster m = moNone;
|
eMonster m = moNone;
|
||||||
do_swords(mf, mt, who, [&] (cell *c, int bb) {
|
do_swords(mi, who, [&] (cell *c, int bb) {
|
||||||
if(!peace::on && canAttack(mt, who, c, c->monst, AF_SWORD) && c->monst && isFriendly(c)) m = c->monst;
|
if(!peace::on && canAttack(mi.t, who, c, c->monst, AF_SWORD) && c->monst && isFriendly(c)) m = c->monst;
|
||||||
});
|
});
|
||||||
|
|
||||||
for(int t=0; t<mf->type; t++) {
|
for(int t=0; t<mi.s->type; t++) {
|
||||||
cell *c = mf->move(t);
|
cell *c = mi.s->move(t);
|
||||||
if(!c) continue;
|
if(!c) continue;
|
||||||
|
|
||||||
bool stabthere = false;
|
bool stabthere = false;
|
||||||
if(logical_adjacent(mt, who, c)) stabthere = true;
|
if(logical_adjacent(mi.t, who, c)) stabthere = true;
|
||||||
|
|
||||||
if(stabthere && canAttack(mt,who,c,c->monst,AF_STAB) && isFriendly(c))
|
if(stabthere && canAttack(mi.t,who,c,c->monst,AF_STAB) && isFriendly(c))
|
||||||
return c->monst;
|
return c->monst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1484,27 +1491,14 @@ EX void wouldkill(const char *msg) {
|
|||||||
addMessage(XLAT("Cannot move into the current location of another player!"));
|
addMessage(XLAT("Cannot move into the current location of another player!"));
|
||||||
else if(who_kills_me == moAirball)
|
else if(who_kills_me == moAirball)
|
||||||
addMessage(XLAT("Players cannot get that far away!"));
|
addMessage(XLAT("Players cannot get that far away!"));
|
||||||
|
else if(who_kills_me == moTongue)
|
||||||
|
addMessage(XLAT("Cannot push into another player!"));
|
||||||
|
else if(who_kills_me == moCrushball)
|
||||||
|
addMessage(XLAT("Cannot push into the same location!"));
|
||||||
else
|
else
|
||||||
addMessage(XLAT(msg, who_kills_me));
|
addMessage(XLAT(msg, who_kills_me));
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool havePushConflict(cell *pushto, bool checkonly) {
|
|
||||||
if(pushto && multi::activePlayers() > 1) {
|
|
||||||
for(int i=0; i<multi::players; i++) if(i != multi::cpid && multi::playerActive(i))
|
|
||||||
if(multi::origpos[i] == pushto || multi::origtarget[i] == pushto) {
|
|
||||||
addMessage(XLAT("Cannot push into another player!"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for(int i=0; i<isize(stalemate::moves); i++) {
|
|
||||||
if(pushto == stalemate::moves[i].pushto) {
|
|
||||||
addMessage(XLAT("Cannot push into the same location!"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EX void movecost(cell* from, cell *to, int phase) {
|
EX void movecost(cell* from, cell *to, int phase) {
|
||||||
if(from->land == laPower && to->land != laPower && (phase & 1)) {
|
if(from->land == laPower && to->land != laPower && (phase & 1)) {
|
||||||
int n=0;
|
int n=0;
|
||||||
|
31
polygons.cpp
31
polygons.cpp
@ -718,24 +718,26 @@ void geometry_information::procedural_shapes() {
|
|||||||
|
|
||||||
vector<ld> equal_weights(1000, 1);
|
vector<ld> equal_weights(1000, 1);
|
||||||
|
|
||||||
#if !(CAP_BT && MAXMDIM >= 4)
|
#if MAXMDIM < 4
|
||||||
void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector<ld> weights) { }
|
void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector<ld> weights) { }
|
||||||
void geometry_information::reserve_wall3d(int i) { }
|
void geometry_information::reserve_wall3d(int i) { }
|
||||||
void geometry_information::create_wall3d() { }
|
void geometry_information::create_wall3d() { }
|
||||||
void geometry_information::compute_cornerbonus() { }
|
void geometry_information::compute_cornerbonus() { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CAP_BT && MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
|
|
||||||
// Make a wall
|
// Make a wall
|
||||||
|
|
||||||
hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) {
|
hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) {
|
||||||
if(geometry == gNil && among(id, 2, 5)) h[2] = 0;
|
if(geometry == gNil && among(id, 2, 5)) h[2] = 0;
|
||||||
|
#if CAP_BT
|
||||||
if(hyperbolic && bt::in()) {
|
if(hyperbolic && bt::in()) {
|
||||||
// ld co = vid.binary_width / log(2) / 4;
|
// ld co = vid.binary_width / log(2) / 4;
|
||||||
// hyperpoint res = point31(h[2]*log(2)/2, h[0]*co, h[1]*co);
|
// hyperpoint res = point31(h[2]*log(2)/2, h[0]*co, h[1]*co);
|
||||||
return deparabolic10(bt::parabolic3(h[0], h[1]) * xpush0(log(2)/2*h[2]));
|
return deparabolic10(bt::parabolic3(h[0], h[1]) * xpush0(log(2)/2*h[2]));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(prod) {
|
if(prod) {
|
||||||
return point3(h[0]/h[2], h[1]/h[2], pz);
|
return point3(h[0]/h[2], h[1]/h[2], pz);
|
||||||
}
|
}
|
||||||
@ -756,7 +758,9 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
|
|||||||
reverse(vertices.begin(), vertices.end()),
|
reverse(vertices.begin(), vertices.end()),
|
||||||
reverse(weights.begin(), weights.end());
|
reverse(weights.begin(), weights.end());
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
ld yy = log(2) / 2;
|
ld yy = log(2) / 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
bshape(shWall3D[id], PPR::WALL);
|
bshape(shWall3D[id], PPR::WALL);
|
||||||
last->flags |= POLY_TRIANGLES | POLY_PRINTABLE;
|
last->flags |= POLY_TRIANGLES | POLY_PRINTABLE;
|
||||||
@ -815,8 +819,13 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
|
|||||||
hpcpush(h); return;
|
hpcpush(h); return;
|
||||||
}
|
}
|
||||||
if(sn::in() || !bt::in()) { hpcpush(ultra_normalize(h)); return; }
|
if(sn::in() || !bt::in()) { hpcpush(ultra_normalize(h)); return; }
|
||||||
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
|
#if CAP_BT
|
||||||
hpcpush(res);
|
if(bt::in()) {
|
||||||
|
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
|
||||||
|
hpcpush(res);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
hpcpush(h);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,8 +842,13 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
|
|||||||
if(nil)
|
if(nil)
|
||||||
h = nilv::on_geodesic(vertices[a], vertices[(a+1)%n], y * 1. / STEP);
|
h = nilv::on_geodesic(vertices[a], vertices[(a+1)%n], y * 1. / STEP);
|
||||||
if(sn::in() || !bt::in()) { hpcpush(ultra_normalize(h)); continue; }
|
if(sn::in() || !bt::in()) { hpcpush(ultra_normalize(h)); continue; }
|
||||||
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
|
#if CAP_BT
|
||||||
hpcpush(res);
|
if(bt::in()) {
|
||||||
|
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
|
||||||
|
hpcpush(res);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
hpcpush(h);
|
||||||
}
|
}
|
||||||
hpcpush(hpc[last->s]);
|
hpcpush(hpc[last->s]);
|
||||||
}
|
}
|
||||||
@ -875,6 +889,8 @@ void geometry_information::reserve_wall3d(int i) {
|
|||||||
void geometry_information::create_wall3d() {
|
void geometry_information::create_wall3d() {
|
||||||
if(WDIM == 2) return;
|
if(WDIM == 2) return;
|
||||||
reserve_wall3d(kite::in() ? 22 : hybri ? 0 : S7);
|
reserve_wall3d(kite::in() ? 22 : hybri ? 0 : S7);
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
if(GDIM == 3 && bt::in() && geometry == gBinary3) {
|
if(GDIM == 3 && bt::in() && geometry == gBinary3) {
|
||||||
hyperpoint h00 = point3(-1,-1,-1);
|
hyperpoint h00 = point3(-1,-1,-1);
|
||||||
hyperpoint h01 = point3(-1,0,-1);
|
hyperpoint h01 = point3(-1,0,-1);
|
||||||
@ -970,6 +986,7 @@ void geometry_information::create_wall3d() {
|
|||||||
make_wall(12, {point3(3*h,r3,z), point3(0,2*r3,z), point3(-3*h,r3,z)});
|
make_wall(12, {point3(3*h,r3,z), point3(0,2*r3,z), point3(-3*h,r3,z)});
|
||||||
make_wall(13, {point3(3*h,r3,z), point3(3*h,-r3,z), point3(0,-2*r3,z), point3(-3*h,-r3,z), point3(-3*h,r3,z)});
|
make_wall(13, {point3(3*h,r3,z), point3(3*h,-r3,z), point3(0,-2*r3,z), point3(-3*h,-r3,z), point3(-3*h,r3,z)});
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(prod) {
|
if(prod) {
|
||||||
walloffsets.clear();
|
walloffsets.clear();
|
||||||
@ -1060,6 +1077,7 @@ void geometry_information::create_wall3d() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
if(kite::in()) {
|
if(kite::in()) {
|
||||||
auto kv = kite::make_walls();
|
auto kv = kite::make_walls();
|
||||||
for(auto& v: kv.first) for(auto& h: v) {
|
for(auto& v: kv.first) for(auto& h: v) {
|
||||||
@ -1068,6 +1086,7 @@ void geometry_information::create_wall3d() {
|
|||||||
}
|
}
|
||||||
for(int i=0; i<isize(kv.first); i++) make_wall(i, kv.first[i], kv.second[i]);
|
for(int i=0; i<isize(kv.first); i++) make_wall(i, kv.first[i], kv.second[i]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
wallstart.push_back(isize(raywall));
|
wallstart.push_back(isize(raywall));
|
||||||
compute_cornerbonus();
|
compute_cornerbonus();
|
||||||
|
8
quit.cpp
8
quit.cpp
@ -321,7 +321,11 @@ EX void showMission() {
|
|||||||
);
|
);
|
||||||
keyhandler = handleKeyQuit;
|
keyhandler = handleKeyQuit;
|
||||||
|
|
||||||
|
#if CAP_COMPLEX2
|
||||||
bool sweeper = mine::in_minesweeper();
|
bool sweeper = mine::in_minesweeper();
|
||||||
|
#else
|
||||||
|
const bool sweeper = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!peace::on && !racing::on && !sweeper)
|
if(!peace::on && !racing::on && !sweeper)
|
||||||
dialog::addInfo(XLAT("Your score: %1", its(gold())));
|
dialog::addInfo(XLAT("Your score: %1", its(gold())));
|
||||||
@ -335,6 +339,7 @@ EX void showMission() {
|
|||||||
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
|
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
|
||||||
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
|
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
|
||||||
}
|
}
|
||||||
|
#if CAP_COMPLEX2
|
||||||
else if(mine::in_minesweeper()) {
|
else if(mine::in_minesweeper()) {
|
||||||
int to_uncover = kills[moBomberbird];
|
int to_uncover = kills[moBomberbird];
|
||||||
if(to_uncover) {
|
if(to_uncover) {
|
||||||
@ -346,7 +351,8 @@ EX void showMission() {
|
|||||||
dialog::addInfo(XLAT("You won in %1", getgametime_s(mine::victory_time)));
|
dialog::addInfo(XLAT("You won in %1", getgametime_s(mine::victory_time)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
#endif
|
||||||
|
else {
|
||||||
if(0)
|
if(0)
|
||||||
;
|
;
|
||||||
#if CAP_TOUR
|
#if CAP_TOUR
|
||||||
|
@ -32,9 +32,9 @@ EX namespace quotientspace {
|
|||||||
|
|
||||||
int rv(int x) { return (rvadd+x*rvdir) % S7; }
|
int rv(int x) { return (rvadd+x*rvdir) % S7; }
|
||||||
|
|
||||||
constexpr int symmask = (1<<30);
|
|
||||||
|
|
||||||
#if HDR
|
#if HDR
|
||||||
|
constexpr int symmask = (1<<30);
|
||||||
|
|
||||||
struct code {
|
struct code {
|
||||||
vector<int> connections;
|
vector<int> connections;
|
||||||
|
|
||||||
|
@ -755,7 +755,7 @@ EX transmatrix track_matrix(int at, int dir) {
|
|||||||
transmatrix res = unshift(ggmatrix(racing::track[at]));
|
transmatrix res = unshift(ggmatrix(racing::track[at]));
|
||||||
while(true) {
|
while(true) {
|
||||||
if(at+dir < 0 || at+dir >= isize(racing::track)) return res;
|
if(at+dir < 0 || at+dir >= isize(racing::track)) return res;
|
||||||
for(int x=0; x<MDIM; x++) for(int y=0; y<MDIM; y++)
|
for(int x=0; x<MXDIM; x++) for(int y=0; y<MXDIM; y++)
|
||||||
if(abs(res[y][x]) > 10000) return res;
|
if(abs(res[y][x]) > 10000) return res;
|
||||||
cell *cur = racing::track[at];
|
cell *cur = racing::track[at];
|
||||||
at += dir;
|
at += dir;
|
||||||
|
@ -27,7 +27,11 @@ EX ld exp_start = 1;
|
|||||||
EX ld exp_decay_exp = 4;
|
EX ld exp_decay_exp = 4;
|
||||||
EX ld exp_decay_poly = 10;
|
EX ld exp_decay_poly = 10;
|
||||||
|
|
||||||
|
#ifdef GLES_ONLY
|
||||||
|
const int gms_limit = 16; /* enough for Bringris -- need to do better */
|
||||||
|
#else
|
||||||
const int gms_limit = 110;
|
const int gms_limit = 110;
|
||||||
|
#endif
|
||||||
|
|
||||||
EX ld maxstep_sol = .05;
|
EX ld maxstep_sol = .05;
|
||||||
EX ld maxstep_nil = .1;
|
EX ld maxstep_nil = .1;
|
||||||
@ -39,7 +43,8 @@ static const int NO_LIMIT = 999999;
|
|||||||
|
|
||||||
EX ld hard_limit = NO_LIMIT;
|
EX ld hard_limit = NO_LIMIT;
|
||||||
|
|
||||||
EX int max_iter_sol = 600, max_iter_iso = 60;
|
EX int max_iter_sol = 600;
|
||||||
|
EX int max_iter_iso = 60;
|
||||||
|
|
||||||
EX int max_cells = 2048;
|
EX int max_cells = 2048;
|
||||||
EX bool rays_generate = true;
|
EX bool rays_generate = true;
|
||||||
@ -170,6 +175,8 @@ int deg, irays;
|
|||||||
|
|
||||||
#ifdef GLES_ONLY
|
#ifdef GLES_ONLY
|
||||||
void add(string& tgt, string type, string name, int min_index, int max_index) {
|
void add(string& tgt, string type, string name, int min_index, int max_index) {
|
||||||
|
if(min_index >= max_index) ;
|
||||||
|
else
|
||||||
if(min_index + 1 == max_index)
|
if(min_index + 1 == max_index)
|
||||||
tgt += "{ return " + name + "[" + its(min_index) + "]; }";
|
tgt += "{ return " + name + "[" + its(min_index) + "]; }";
|
||||||
else {
|
else {
|
||||||
@ -193,6 +200,11 @@ string build_getter(string type, string name, int index) {
|
|||||||
#define GET(array, index) array "[" index "]"
|
#define GET(array, index) array "[" index "]"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void replace_str(string& s, string a, string b) {
|
||||||
|
while(s.find(a) != string::npos)
|
||||||
|
s.replace(s.find(a), isize(a), b);
|
||||||
|
}
|
||||||
|
|
||||||
EX hookset<void(string&, string&)> hooks_rayshader;
|
EX hookset<void(string&, string&)> hooks_rayshader;
|
||||||
EX hookset<bool(shared_ptr<raycaster>)> hooks_rayset;
|
EX hookset<bool(shared_ptr<raycaster>)> hooks_rayset;
|
||||||
|
|
||||||
@ -216,6 +228,7 @@ void enable_raycaster() {
|
|||||||
bool use_reflect = reflect_val && !nil && !levellines;
|
bool use_reflect = reflect_val && !nil && !levellines;
|
||||||
|
|
||||||
bool bi = arcm::in() || kite::in() || arb::in() || !PURE;
|
bool bi = arcm::in() || kite::in() || arb::in() || !PURE;
|
||||||
|
bi = false;
|
||||||
|
|
||||||
string vsh =
|
string vsh =
|
||||||
"attribute mediump vec4 aPosition;\n"
|
"attribute mediump vec4 aPosition;\n"
|
||||||
@ -269,11 +282,13 @@ void enable_raycaster() {
|
|||||||
int flat1 = 0, flat2 = deg;
|
int flat1 = 0, flat2 = deg;
|
||||||
if(prod || rotspace) flat2 -= 2;
|
if(prod || rotspace) flat2 -= 2;
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
if(hyperbolic && bt::in()) {
|
if(hyperbolic && bt::in()) {
|
||||||
fsh += "uniform mediump float uBLevel;\n";
|
fsh += "uniform mediump float uBLevel;\n";
|
||||||
flat1 = bt::dirs_outer();
|
flat1 = bt::dirs_outer();
|
||||||
flat2 -= bt::dirs_inner();
|
flat2 -= bt::dirs_inner();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(hyperbolic) fsh +=
|
if(hyperbolic) fsh +=
|
||||||
|
|
||||||
@ -355,14 +370,34 @@ void enable_raycaster() {
|
|||||||
" mediump mat4 vw = uStart * xzspin(-lambda) * xpush(eye) * yzspin(phi);\n"
|
" mediump mat4 vw = uStart * xzspin(-lambda) * xpush(eye) * yzspin(phi);\n"
|
||||||
" mediump vec4 at0 = vec4(0., 0., 1., 0.);\n";
|
" mediump vec4 at0 = vec4(0., 0., 1., 0.);\n";
|
||||||
|
|
||||||
else fmain +=
|
else {
|
||||||
" mediump mat4 vw = uStart;\n"
|
fmain +=
|
||||||
" mediump vec4 at0 = at;\n"
|
" mediump mat4 vw = uStart;\n"
|
||||||
" gl_FragColor = vec4(0,0,0,1);\n"
|
" mediump vec4 at0 = at;\n"
|
||||||
" mediump float left = 1.;\n"
|
" gl_FragColor = vec4(0,0,0,1);\n"
|
||||||
" at0.y = -at.y;\n"
|
" mediump float left = 1.;\n"
|
||||||
" at0.w = 0.;\n"
|
" at0.y = -at.y;\n"
|
||||||
" at0.xyz = at0.xyz / length(at0.xyz);\n";
|
" at0.w = 0.;\n";
|
||||||
|
|
||||||
|
if(panini_alpha) fmain +=
|
||||||
|
"mediump float hr = at0.x*at0.x;\n"
|
||||||
|
"mediump float alpha = " + to_glsl(panini_alpha) + ";\n"
|
||||||
|
"mediump float A = 1. + hr;\n"
|
||||||
|
"mediump float B = -2.*hr*alpha;\n"
|
||||||
|
"mediump float C = 1. - hr*alpha*alpha;\n"
|
||||||
|
"B /= A; C /= A;\n"
|
||||||
|
|
||||||
|
"mediump float hz = B / 2. + sqrt(C + B*B/4.);\n"
|
||||||
|
"if(abs(hz) > 1e-3) {"
|
||||||
|
"at0.xyz *= hz+alpha;\n"
|
||||||
|
"at0.z = hz;\n}"
|
||||||
|
" else at0.z = 0.;\n"
|
||||||
|
"\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
fmain +=
|
||||||
|
" at0.xyz = at0.xyz / length(at0.xyz);\n";
|
||||||
|
}
|
||||||
|
|
||||||
if(hyperbolic) fsh += " mediump float len(mediump vec4 x) { return x[3]; }\n";
|
if(hyperbolic) fsh += " mediump float len(mediump vec4 x) { return x[3]; }\n";
|
||||||
else if(sphere && rotspace) fsh += " mediump float len(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y-x.z*x.z-x.w*x.w; }\n";
|
else if(sphere && rotspace) fsh += " mediump float len(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y-x.z*x.z-x.w*x.w; }\n";
|
||||||
@ -454,7 +489,7 @@ void enable_raycaster() {
|
|||||||
|
|
||||||
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : WDIM == 2 ? "sides" : its(flat2))+"; i++) {\n";
|
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : WDIM == 2 ? "sides" : its(flat2))+"; i++) {\n";
|
||||||
|
|
||||||
fmain += "int woi = walloffset+i;\n";
|
// fmain += "int woi = walloffset+i;\n";
|
||||||
|
|
||||||
if(in_h2xe()) fmain +=
|
if(in_h2xe()) fmain +=
|
||||||
" mediump float v = ((position - uM[woi] * position)[2] / (uM[woi] * tangent - tangent)[2]);\n"
|
" mediump float v = ((position - uM[woi] * position)[2] / (uM[woi] * tangent - tangent)[2]);\n"
|
||||||
@ -495,6 +530,8 @@ void enable_raycaster() {
|
|||||||
" if(d < 0.) continue;\n"
|
" if(d < 0.) continue;\n"
|
||||||
" mediump vec4 next_position = position + d * tangent;\n"
|
" mediump vec4 next_position = position + d * tangent;\n"
|
||||||
" if(dot(next_position, tangent) < dot(uM[woi]*next_position, uM[woi]*tangent)) continue;\n";
|
" if(dot(next_position, tangent) < dot(uM[woi]*next_position, uM[woi]*tangent)) continue;\n";
|
||||||
|
|
||||||
|
replace_str(fmain, "[woi]", "[walloffset+i]");
|
||||||
|
|
||||||
fmain +=
|
fmain +=
|
||||||
" if(d < dist) { dist = d; which = i; }\n"
|
" if(d < dist) { dist = d; which = i; }\n"
|
||||||
@ -964,6 +1001,11 @@ void enable_raycaster() {
|
|||||||
"tangent -= dot(vec4(-position.xyz, position.w), tangent) * position;\n"
|
"tangent -= dot(vec4(-position.xyz, position.w), tangent) * position;\n"
|
||||||
"tangent /= sqrt(dot(tangent.xyz, tangent.xyz) - tangent.w*tangent.w);\n";
|
"tangent /= sqrt(dot(tangent.xyz, tangent.xyz) - tangent.w*tangent.w);\n";
|
||||||
|
|
||||||
|
if(in_h2xe()) fmain +=
|
||||||
|
"position /= sqrt(position.z*position.z - dot(position.xy, position.xy));\n"
|
||||||
|
"tangent -= dot(vec3(-position.xy, position.z), tangent.xyz) * position;\n"
|
||||||
|
"tangent /= sqrt(dot(tangent.xy, tangent.xy) - tangent.z*tangent.z);\n";
|
||||||
|
|
||||||
if(hyperbolic && bt::in()) {
|
if(hyperbolic && bt::in()) {
|
||||||
fmain +=
|
fmain +=
|
||||||
"if(which == 20) {\n"
|
"if(which == 20) {\n"
|
||||||
@ -1054,11 +1096,12 @@ void enable_raycaster() {
|
|||||||
" if(col.w == 1.) {\n";
|
" if(col.w == 1.) {\n";
|
||||||
|
|
||||||
if(hyperbolic) fmain +=
|
if(hyperbolic) fmain +=
|
||||||
" mediump float z = at0.z * sinh(go);\n"
|
" mediump vec4 t = at0 * sinh(go);\n";
|
||||||
" mediump float w = 1.;\n";
|
|
||||||
else fmain +=
|
else fmain +=
|
||||||
" mediump float z = at0.z * go;\n"
|
" mediump vec4 t = at0 * go;\n";
|
||||||
" mediump float w = 1.;\n";
|
|
||||||
|
fmain +=
|
||||||
|
" t.w = 1.;\n";
|
||||||
|
|
||||||
if(levellines) {
|
if(levellines) {
|
||||||
if(hyperbolic)
|
if(hyperbolic)
|
||||||
@ -1067,10 +1110,13 @@ void enable_raycaster() {
|
|||||||
fmain += "gl_FragColor.xyz *= 0.5 + 0.5 * cos(z * uLevelLines * 2. * PI);\n";
|
fmain += "gl_FragColor.xyz *= 0.5 + 0.5 * cos(z * uLevelLines * 2. * PI);\n";
|
||||||
fsh += "uniform mediump float uLevelLines;\n";
|
fsh += "uniform mediump float uLevelLines;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(panini_alpha)
|
||||||
|
fmain += panini_shader();
|
||||||
|
|
||||||
#ifndef GLES_ONLY
|
#ifndef GLES_ONLY
|
||||||
fmain +=
|
fmain +=
|
||||||
" gl_FragDepth = (" + to_glsl(-vnear-vfar)+"+w*" + to_glsl(2*vnear*vfar)+"/z)/" + to_glsl(vnear-vfar)+";\n"
|
" gl_FragDepth = (" + to_glsl(-vnear-vfar)+"+t.w*" + to_glsl(2*vnear*vfar)+"/t.z)/" + to_glsl(vnear-vfar)+";\n"
|
||||||
" gl_FragDepth = (gl_FragDepth + 1.) / 2.;\n";
|
" gl_FragDepth = (gl_FragDepth + 1.) / 2.;\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1195,12 +1241,20 @@ void bind_array(vector<array<float, 4>>& v, GLint t, GLuint& tx, int id) {
|
|||||||
if(tx == 0) glGenTextures(1, &tx);
|
if(tx == 0) glGenTextures(1, &tx);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + id);
|
glActiveTexture(GL_TEXTURE0 + id);
|
||||||
|
GLERR("activeTexture");
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tx);
|
glBindTexture(GL_TEXTURE_2D, tx);
|
||||||
|
GLERR("bindTexture");
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
GLERR("texParameteri");
|
||||||
|
|
||||||
|
#ifdef GLES_ONLY
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, length, isize(v)/length, 0, GL_RGBA, GL_FLOAT, &v[0]);
|
||||||
|
#else
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, 0x8814 /* GL_RGBA32F */, length, isize(v)/length, 0, GL_RGBA, GL_FLOAT, &v[0]);
|
glTexImage2D(GL_TEXTURE_2D, 0, 0x8814 /* GL_RGBA32F */, length, isize(v)/length, 0, GL_RGBA, GL_FLOAT, &v[0]);
|
||||||
|
#endif
|
||||||
GLERR("bind_array");
|
GLERR("bind_array");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1533,8 +1587,11 @@ EX void cast() {
|
|||||||
}
|
}
|
||||||
if(o->uPLevel != -1)
|
if(o->uPLevel != -1)
|
||||||
glUniform1f(o->uPLevel, cgi.plevel / 2);
|
glUniform1f(o->uPLevel, cgi.plevel / 2);
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
if(o->uBLevel != -1)
|
if(o->uBLevel != -1)
|
||||||
glUniform1f(o->uBLevel, log(bt::expansion()) / 2);
|
glUniform1f(o->uBLevel, log(bt::expansion()) / 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(o->uLinearSightRange != -1)
|
if(o->uLinearSightRange != -1)
|
||||||
glUniform1f(o->uLinearSightRange, sightranges[geometry]);
|
glUniform1f(o->uLinearSightRange, sightranges[geometry]);
|
||||||
@ -1560,7 +1617,13 @@ EX void cast() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CAP_VERTEXBUFFER
|
||||||
|
glhr::bindbuffer_vertex(screen);
|
||||||
|
glVertexAttribPointer(hr::aPosition, 4, GL_FLOAT, GL_FALSE, sizeof(glvertex), 0);
|
||||||
|
#else
|
||||||
glVertexAttribPointer(hr::aPosition, 4, GL_FLOAT, GL_FALSE, sizeof(glvertex), &screen[0]);
|
glVertexAttribPointer(hr::aPosition, 4, GL_FLOAT, GL_FALSE, sizeof(glvertex), &screen[0]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(ray::comparison_mode)
|
if(ray::comparison_mode)
|
||||||
glhr::set_depthtest(false);
|
glhr::set_depthtest(false);
|
||||||
else {
|
else {
|
||||||
@ -1572,6 +1635,7 @@ EX void cast() {
|
|||||||
glActiveTexture(GL_TEXTURE0 + 0);
|
glActiveTexture(GL_TEXTURE0 + 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, floor_textures->renderedTexture);
|
glBindTexture(GL_TEXTURE_2D, floor_textures->renderedTexture);
|
||||||
|
|
||||||
|
GLERR("bind");
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
GLERR("finish");
|
GLERR("finish");
|
||||||
}
|
}
|
||||||
|
34
reg3.cpp
34
reg3.cpp
@ -13,13 +13,6 @@
|
|||||||
namespace hr {
|
namespace hr {
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
|
|
||||||
namespace binary {
|
|
||||||
void build_tmatrix();
|
|
||||||
void virtualRebaseSimple(heptagon*& base, transmatrix& at);
|
|
||||||
int celldistance3(heptagon *c1, heptagon *c2);
|
|
||||||
hyperpoint deparabolic3(hyperpoint h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief regular three-dimensional tessellations */
|
/** \brief regular three-dimensional tessellations */
|
||||||
EX namespace reg3 {
|
EX namespace reg3 {
|
||||||
|
|
||||||
@ -608,8 +601,8 @@ EX namespace reg3 {
|
|||||||
hrmap *binary_map;
|
hrmap *binary_map;
|
||||||
hrmap_quotient3 *quotient_map;
|
hrmap_quotient3 *quotient_map;
|
||||||
|
|
||||||
unordered_map<heptagon*, pair<heptagon*, transmatrix>> reg_gmatrix;
|
map<heptagon*, pair<heptagon*, transmatrix>> reg_gmatrix;
|
||||||
unordered_map<heptagon*, vector<pair<heptagon*, transmatrix> > > altmap;
|
map<heptagon*, vector<pair<heptagon*, transmatrix> > > altmap;
|
||||||
|
|
||||||
vector<cell*> spherecells;
|
vector<cell*> spherecells;
|
||||||
|
|
||||||
@ -641,10 +634,13 @@ EX namespace reg3 {
|
|||||||
quotient_map = nullptr;
|
quotient_map = nullptr;
|
||||||
|
|
||||||
#if CAP_FIELD
|
#if CAP_FIELD
|
||||||
|
#if CAP_CRYSTAL
|
||||||
if(geometry == gSpace344) {
|
if(geometry == gSpace344) {
|
||||||
quotient_map = new hrmap_from_crystal;
|
quotient_map = new hrmap_from_crystal;
|
||||||
}
|
}
|
||||||
else if(geometry == gSpace535) {
|
else
|
||||||
|
#endif
|
||||||
|
if(geometry == gSpace535) {
|
||||||
quotient_map = new seifert_weber::hrmap_seifert_cover;
|
quotient_map = new seifert_weber::hrmap_seifert_cover;
|
||||||
}
|
}
|
||||||
else if(hyperbolic) {
|
else if(hyperbolic) {
|
||||||
@ -653,6 +649,7 @@ EX namespace reg3 {
|
|||||||
#endif
|
#endif
|
||||||
h.zebraval = quotient_map ? quotient_map->allh[0]->zebraval : 0;
|
h.zebraval = quotient_map ? quotient_map->allh[0]->zebraval : 0;
|
||||||
|
|
||||||
|
#if CAP_BT
|
||||||
if(hyperbolic) {
|
if(hyperbolic) {
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
bt::build_tmatrix();
|
bt::build_tmatrix();
|
||||||
@ -667,6 +664,7 @@ EX namespace reg3 {
|
|||||||
binary_map = bt::new_alt_map(alt);
|
binary_map = bt::new_alt_map(alt);
|
||||||
T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * cspin(0, 2, 1.1249) * xpush(0.07) * Id;
|
T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * cspin(0, 2, 1.1249) * xpush(0.07) * Id;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
reg_gmatrix[origin] = make_pair(alt, T);
|
reg_gmatrix[origin] = make_pair(alt, T);
|
||||||
altmap[alt].emplace_back(origin, T);
|
altmap[alt].emplace_back(origin, T);
|
||||||
@ -730,12 +728,14 @@ EX namespace reg3 {
|
|||||||
println(hlog, "FAIL");
|
println(hlog, "FAIL");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
#if CAP_BT
|
||||||
if(steps) {
|
if(steps) {
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
dynamicval<hrmap*> cm(currentmap, binary_map);
|
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||||
for(int i=0; i<alt->type; i++)
|
for(int i=0; i<alt->type; i++)
|
||||||
verify_neighbors(alt->cmove(i), steps-1, currentmap->iadj(alt, i) * hT);
|
verify_neighbors(alt->cmove(i), steps-1, currentmap->iadj(alt, i) * hT);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *create_step(heptagon *parent, int d) override {
|
heptagon *create_step(heptagon *parent, int d) override {
|
||||||
@ -748,11 +748,13 @@ EX namespace reg3 {
|
|||||||
transmatrix T = p1.second * cgi.adjmoves[d];
|
transmatrix T = p1.second * cgi.adjmoves[d];
|
||||||
#endif
|
#endif
|
||||||
transmatrix T1 = T;
|
transmatrix T1 = T;
|
||||||
|
#if CAP_BT
|
||||||
if(hyperbolic) {
|
if(hyperbolic) {
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
dynamicval<hrmap*> cm(currentmap, binary_map);
|
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||||
binary_map->virtualRebase(alt, T);
|
binary_map->virtualRebase(alt, T);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
fixmatrix(T);
|
fixmatrix(T);
|
||||||
auto hT = tC0(T);
|
auto hT = tC0(T);
|
||||||
@ -852,10 +854,12 @@ EX namespace reg3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~hrmap_reg3() {
|
~hrmap_reg3() {
|
||||||
|
#if CAP_BT
|
||||||
if(binary_map) {
|
if(binary_map) {
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
delete binary_map;
|
delete binary_map;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(quotient_map) delete quotient_map;
|
if(quotient_map) delete quotient_map;
|
||||||
clearfrom(origin);
|
clearfrom(origin);
|
||||||
}
|
}
|
||||||
@ -901,12 +905,14 @@ EX namespace reg3 {
|
|||||||
auto p1 = reg_gmatrix[h1];
|
auto p1 = reg_gmatrix[h1];
|
||||||
auto p2 = reg_gmatrix[h2];
|
auto p2 = reg_gmatrix[h2];
|
||||||
transmatrix T = Id;
|
transmatrix T = Id;
|
||||||
|
#if CAP_BT
|
||||||
if(hyperbolic) {
|
if(hyperbolic) {
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
dynamicval<hrmap*> cm(currentmap, binary_map);
|
dynamicval<hrmap*> cm(currentmap, binary_map);
|
||||||
T = binary_map->relative_matrix(p2.first, p1.first, hint);
|
T = binary_map->relative_matrix(p2.first, p1.first, hint);
|
||||||
}
|
}
|
||||||
T = inverse(p1.second) * T * p2.second;
|
#endif
|
||||||
|
T = inverse(p1.second) * T * p2.second;
|
||||||
if(elliptic && T[LDIM][LDIM] < 0) T = centralsym * T;
|
if(elliptic && T[LDIM][LDIM] < 0) T = centralsym * T;
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
@ -1343,7 +1349,11 @@ EX int celldistance(cell *c1, cell *c2) {
|
|||||||
return clueless_celldistance(c1, c2);
|
return clueless_celldistance(c1, c2);
|
||||||
|
|
||||||
dynamicval<eGeometry> g(geometry, gBinary3);
|
dynamicval<eGeometry> g(geometry, gBinary3);
|
||||||
|
#if CAP_BT
|
||||||
return 20 + bt::celldistance3(r->reg_gmatrix[c1->master].first, r->reg_gmatrix[c2->master].first);
|
return 20 + bt::celldistance3(r->reg_gmatrix[c1->master].first, r->reg_gmatrix[c2->master].first);
|
||||||
|
#else
|
||||||
|
return 20;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool pseudohept(cell *c) {
|
EX bool pseudohept(cell *c) {
|
||||||
@ -1429,7 +1439,7 @@ ld adistance(cell *c) {
|
|||||||
return regmap()->reg_gmatrix[c->master].first->distance * log(2) - h[0];
|
return regmap()->reg_gmatrix[c->master].first->distance * log(2) - h[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_map<pair<cell*, cell*>, int> memo;
|
map<pair<cell*, cell*>, int> memo;
|
||||||
|
|
||||||
bool cdd;
|
bool cdd;
|
||||||
|
|
||||||
|
@ -85,7 +85,9 @@ renderbuffer::renderbuffer(int x, int y, bool gl) : x(x), y(y) {
|
|||||||
|
|
||||||
# if CAP_GL
|
# if CAP_GL
|
||||||
if(gl) {
|
if(gl) {
|
||||||
|
GLERR("renderbuffer init");
|
||||||
resetbuffer rb;
|
resetbuffer rb;
|
||||||
|
GLERR("after resetbuffer");
|
||||||
tx = next_p2(x);
|
tx = next_p2(x);
|
||||||
ty = next_p2(y);
|
ty = next_p2(y);
|
||||||
|
|
||||||
@ -119,7 +121,7 @@ renderbuffer::renderbuffer(int x, int y, bool gl) : x(x), y(y) {
|
|||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, tx, ty);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, tx, ty);
|
||||||
bool has_depth = true;
|
bool has_depth = true;
|
||||||
if(glGetError() != GL_NO_ERROR) {
|
if(glGetError() != GL_NO_ERROR) {
|
||||||
printf("Could not create: GL_DEPTH24_STENCIL8");
|
println(hlog, "Could not create: GL_DEPTH24_STENCIL8");
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, tx, ty);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, tx, ty);
|
||||||
has_depth = false;
|
has_depth = false;
|
||||||
}
|
}
|
||||||
@ -243,7 +245,9 @@ resetbuffer::resetbuffer() {
|
|||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
drawFboId = 0, readFboId = 0;
|
drawFboId = 0, readFboId = 0;
|
||||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFboId);
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFboId);
|
||||||
|
GLERR("getInteger a");
|
||||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFboId);
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFboId);
|
||||||
|
GLERR("getInteger b");
|
||||||
#endif
|
#endif
|
||||||
#if CAP_SDL
|
#if CAP_SDL
|
||||||
sreset = s;
|
sreset = s;
|
||||||
|
1802
rogueviz/bringris.cpp
Normal file
1802
rogueviz/bringris.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ struct jmatrix : array<array<int, 7>, 7> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vector<jmatrix> jms;
|
vector<jmatrix> jms;
|
||||||
std::unordered_map<jmatrix, int> ids;
|
std::map<jmatrix, int> ids;
|
||||||
|
|
||||||
jmatrix J, Z, id;
|
jmatrix J, Z, id;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ void make() {
|
|||||||
for(int i=0; i<magmav; i++) vertices.push_back(vertices[i]);
|
for(int i=0; i<magmav; i++) vertices.push_back(vertices[i]);
|
||||||
for(int i=0; i<magmav; i++) vertices.push_back(vertices[i]);
|
for(int i=0; i<magmav; i++) vertices.push_back(vertices[i]);
|
||||||
|
|
||||||
unordered_map<pair<int, int>, int> counts;
|
map<pair<int, int>, int> counts;
|
||||||
|
|
||||||
int big = v - 2;
|
int big = v - 2;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define main nconf_main
|
#define main nconf_main
|
||||||
#undef unordered_map
|
#undef map
|
||||||
#undef self
|
#undef self
|
||||||
#include "nconf.cpp"
|
#include "nconf.cpp"
|
||||||
#undef main
|
#undef main
|
||||||
|
@ -546,7 +546,7 @@ void queuedisk(const shiftmatrix& V, const colorpair& cp, bool legend, const str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_map<pair<edgeinfo*, int>, int> drawn_edges;
|
map<pair<edgeinfo*, int>, int> drawn_edges;
|
||||||
|
|
||||||
map<pair<cell*, cell*>, transmatrix> relmatrices;
|
map<pair<cell*, cell*>, transmatrix> relmatrices;
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ void starbattle_puzzle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keyhandler = [] (int sym, int uni) {
|
keyhandler = [] (int sym, int uni) {
|
||||||
handlePanning(sym, uni);
|
if(!dialog_shown) handlePanning(sym, uni);
|
||||||
dialog::handleNavigation(sym, uni);
|
dialog::handleNavigation(sym, uni);
|
||||||
|
|
||||||
if(among(sym, '-', SDLK_F1) && !holdmouse) push_stop();
|
if(among(sym, '-', SDLK_F1) && !holdmouse) push_stop();
|
||||||
|
179
rogueviz/subquotient.cpp
Normal file
179
rogueviz/subquotient.cpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#include "../hyper.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace hr {
|
||||||
|
|
||||||
|
namespace subquotient {
|
||||||
|
|
||||||
|
eGeometry gSubquotient(eGeometry(-1));
|
||||||
|
|
||||||
|
vector<int> connections;
|
||||||
|
|
||||||
|
void create_subquotient(int qty = -1, int id = 0) {
|
||||||
|
start_game();
|
||||||
|
auto ac = currentmap->allcells();
|
||||||
|
auto ca = currentmap->gamestart();
|
||||||
|
|
||||||
|
for(auto cb: ac) for(int i=0; i<cb->type; i++) for(int m=0; m<2; m++) {
|
||||||
|
vector<cell*> visited;
|
||||||
|
map<cell*, cellwalker> vmap;
|
||||||
|
|
||||||
|
auto visit = [&] (cell *da, cellwalker db) {
|
||||||
|
if(vmap.count(da)) {
|
||||||
|
// println(hlog, da, " -> ", db, " [old]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// println(hlog, da, " -> ", db, " [new]");
|
||||||
|
vmap[da] = db;
|
||||||
|
visited.emplace_back(da);
|
||||||
|
};
|
||||||
|
|
||||||
|
visit(ca, cellwalker(cb, i, m));
|
||||||
|
|
||||||
|
for(int i=0; i<isize(visited); i++) {
|
||||||
|
for(int j=0; j<visited[i]->type; j++) {
|
||||||
|
cellwalker wa(visited[i], 0);
|
||||||
|
cellwalker wb(vmap[visited[i]]);
|
||||||
|
wa += j;
|
||||||
|
wb += j;
|
||||||
|
wa += wstep;
|
||||||
|
wb += wstep;
|
||||||
|
int r = wa.spin;
|
||||||
|
wa -= r;
|
||||||
|
wb -= r;
|
||||||
|
// println(hlog, wa, " -> ", wb);
|
||||||
|
setdist(wa.at, 7, nullptr);
|
||||||
|
wa.at->item = itGold;
|
||||||
|
visit(wa.at, wb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vertex = 0, edge = 0, badcycle = 0;
|
||||||
|
|
||||||
|
map<int, int> by_cycle;
|
||||||
|
|
||||||
|
for(auto swb: vmap) {
|
||||||
|
auto& s = swb.first;
|
||||||
|
auto& wb = swb.second;
|
||||||
|
if(s == wb.at) { vertex++; continue; }
|
||||||
|
bool is_edge = false;
|
||||||
|
for(int j=0; j<s->type; j++) if(s->move(j) == wb.at && (wb+j).peek() == s)
|
||||||
|
is_edge = true;
|
||||||
|
if(is_edge) { edge++; continue; }
|
||||||
|
int cs = 0;
|
||||||
|
cell *sx = s;
|
||||||
|
auto cw = cellwalker(s, 0);
|
||||||
|
vector<cell*> lst;
|
||||||
|
do {
|
||||||
|
int sp = cw.spin;
|
||||||
|
bool mirr = cw.mirrored;
|
||||||
|
if(cw.mirrored) sp = -sp;
|
||||||
|
cw -= sp;
|
||||||
|
lst.push_back(sx);
|
||||||
|
cw = vmap[sx];
|
||||||
|
if(mirr) cw += wmirror;
|
||||||
|
sx = cw.at;
|
||||||
|
cw += sp;
|
||||||
|
cs++;
|
||||||
|
if(cs >= 100) break;
|
||||||
|
}
|
||||||
|
while(sx != s);
|
||||||
|
if(cw.spin) badcycle++;
|
||||||
|
by_cycle[cs]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vertex || edge || badcycle || m == 0) continue;
|
||||||
|
|
||||||
|
vector<pair<int, int>> bcp;
|
||||||
|
for(auto b: by_cycle) bcp.push_back(b);
|
||||||
|
|
||||||
|
if(qty == -1)
|
||||||
|
println(hlog, "m=", m, " vertex/edge = ", tie(vertex, edge), " badcycle = ", badcycle, " by_cycle = ", bcp);
|
||||||
|
|
||||||
|
if(by_cycle[qty] == isize(vmap)) {
|
||||||
|
if(id > 0) {id--; continue; }
|
||||||
|
|
||||||
|
map<cell*, int> ids;
|
||||||
|
int next_id = 0;
|
||||||
|
vector<cell*> by_id;
|
||||||
|
|
||||||
|
set<cell*> visited;
|
||||||
|
|
||||||
|
for(auto s: ac) if(!visited.count(s)) {
|
||||||
|
by_id.push_back(s);
|
||||||
|
ids[s] = next_id;
|
||||||
|
auto sx = s;
|
||||||
|
do {
|
||||||
|
visited.insert(sx);
|
||||||
|
sx = vmap[sx].at;
|
||||||
|
}
|
||||||
|
while(sx != s);
|
||||||
|
next_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
println(hlog, "ids = ", next_id);
|
||||||
|
connections.clear();
|
||||||
|
if(int(gSubquotient) == -1) {
|
||||||
|
ginf.push_back(ginf[geometry]);
|
||||||
|
gSubquotient = eGeometry(isize(ginf) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ginf[gSubquotient] = ginf[geometry];
|
||||||
|
/* we need to be 'pure', unrectified may not work */
|
||||||
|
if(UNRECTIFIED) swap(ginf[gSubquotient].sides, ginf[gSubquotient].vertex);
|
||||||
|
|
||||||
|
for(int i=0; i<next_id; i++) {
|
||||||
|
cell *s = by_id[i];
|
||||||
|
for(int j=0; j<s->type; j++) {
|
||||||
|
cellwalker cw(s, j);
|
||||||
|
cw += wstep;
|
||||||
|
int res;
|
||||||
|
while(!ids.count(cw.at)) {
|
||||||
|
int sp = cw.spin;
|
||||||
|
bool flip = cw.mirrored;
|
||||||
|
if(flip) sp = -sp;
|
||||||
|
cw -= sp;
|
||||||
|
if(cw.spin) println(hlog, "bad spin");
|
||||||
|
cw = vmap[cw.at];
|
||||||
|
if(flip) cw += wmirror;
|
||||||
|
cw += sp;
|
||||||
|
}
|
||||||
|
res = ids[cw.at] * s->type + cw.spin;
|
||||||
|
if(cw.mirrored) res |= quotientspace::symmask;
|
||||||
|
connections.push_back(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_game();
|
||||||
|
set_geometry(gSubquotient);
|
||||||
|
variation = eVariation::pure;
|
||||||
|
println(hlog, "variation = ", int(variation));
|
||||||
|
start_game();
|
||||||
|
println(hlog, "started");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int readArgs() {
|
||||||
|
using namespace arg;
|
||||||
|
|
||||||
|
if(0) ;
|
||||||
|
else if(argis("-subquotient")) { start_game(); shift(); create_subquotient(argi()); }
|
||||||
|
|
||||||
|
else return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fundamentalhook = addHook(hooks_args, 100, readArgs)
|
||||||
|
+ addHook(hooks_newmap, 0, [] {
|
||||||
|
if(geometry == gSubquotient)
|
||||||
|
return (hrmap*) new quotientspace::hrmap_quotient(connections);
|
||||||
|
return (hrmap*) nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
rug.cpp
6
rug.cpp
@ -631,7 +631,7 @@ bool force(rugpoint& m1, rugpoint& m2, double rd, bool is_anticusp=false, double
|
|||||||
|
|
||||||
transmatrix iT = rgpushxto0(m1.native);
|
transmatrix iT = rgpushxto0(m1.native);
|
||||||
|
|
||||||
for(int i=0; i<MDIM; i++) if(std::isnan(m1.native[i])) {
|
for(int i=0; i<MXDIM; i++) if(std::isnan(m1.native[i])) {
|
||||||
addMessage("Failed!");
|
addMessage("Failed!");
|
||||||
println(hlog, "m1 = ", m1.native);
|
println(hlog, "m1 = ", m1.native);
|
||||||
throw rug_exception();
|
throw rug_exception();
|
||||||
@ -1850,11 +1850,15 @@ EX namespace rug {
|
|||||||
EX bool rugged = false;
|
EX bool rugged = false;
|
||||||
EX bool renderonce = false;
|
EX bool renderonce = false;
|
||||||
EX bool rendernogl = true;
|
EX bool rendernogl = true;
|
||||||
|
EX bool mouse_control_rug = false;
|
||||||
EX int texturesize = 512;
|
EX int texturesize = 512;
|
||||||
EX ld scale = 1.0f;
|
EX ld scale = 1.0f;
|
||||||
EX bool rug_control() { return false; }
|
EX bool rug_control() { return false; }
|
||||||
EX bool in_crystal() { return false; }
|
EX bool in_crystal() { return false; }
|
||||||
EX void reset_view() { }
|
EX void reset_view() { }
|
||||||
|
#if HDR
|
||||||
|
struct using_rugview {};
|
||||||
|
#endif
|
||||||
EX }
|
EX }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1815,6 +1815,7 @@ void no_init() { }
|
|||||||
|
|
||||||
startanim null_animation { "", no_init, [] { gamescreen(2); }};
|
startanim null_animation { "", no_init, [] { gamescreen(2); }};
|
||||||
|
|
||||||
|
#if CAP_STARTANIM
|
||||||
startanim joukowsky { "Joukowsky transform", no_init, [] {
|
startanim joukowsky { "Joukowsky transform", no_init, [] {
|
||||||
dynamicval<eModel> dm(pmodel, mdJoukowskyInverted);
|
dynamicval<eModel> dm(pmodel, mdJoukowskyInverted);
|
||||||
dynamicval<ld> dt(pconf.model_orientation, ticks / 25.);
|
dynamicval<ld> dt(pconf.model_orientation, ticks / 25.);
|
||||||
@ -1874,6 +1875,7 @@ startanim spin_around { "spinning around", no_init, [] {
|
|||||||
dynamicval<transmatrix> dv(View, spin(-cos_auto(circle_radius)*alpha) * xpush(circle_radius) * spin(alpha) * View);
|
dynamicval<transmatrix> dv(View, spin(-cos_auto(circle_radius)*alpha) * xpush(circle_radius) * spin(alpha) * View);
|
||||||
gamescreen(2);
|
gamescreen(2);
|
||||||
}};
|
}};
|
||||||
|
#endif
|
||||||
|
|
||||||
reaction_t add_to_frame;
|
reaction_t add_to_frame;
|
||||||
|
|
||||||
|
37
shaders.cpp
37
shaders.cpp
@ -60,6 +60,23 @@ glhr::glmatrix model_orientation_gl() {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX void reset_all_shaders() {
|
||||||
|
ray::reset_raycaster();
|
||||||
|
compiled_programs.clear();
|
||||||
|
matched_programs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
EX string panini_shader() {
|
||||||
|
return
|
||||||
|
"t.w += 1.; t *= 2. / t.w; t.w -= 1.;\n"
|
||||||
|
"float s = t.z;\n"
|
||||||
|
"float l = length(t.xyz);\n"
|
||||||
|
"t /= max(length(t.xz), 1e-2);\n"
|
||||||
|
"t.z += " + glhr::to_glsl(panini_alpha) + ";\n"
|
||||||
|
"t *= l;\n"
|
||||||
|
"t.w = 1.;\n";
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
|
shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
|
||||||
string varying, vsh, fsh, vmain = "void main() {\n", fmain = "void main() {\n";
|
string varying, vsh, fsh, vmain = "void main() {\n", fmain = "void main() {\n";
|
||||||
|
|
||||||
@ -332,6 +349,14 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
|
|||||||
}
|
}
|
||||||
if(shader_flags & GF_LEVELS) vmain += "vPos = t;\n";
|
if(shader_flags & GF_LEVELS) vmain += "vPos = t;\n";
|
||||||
if(treset) vmain += "t[3] = 1.0;\n";
|
if(treset) vmain += "t[3] = 1.0;\n";
|
||||||
|
|
||||||
|
if(WDIM == 3 && panini_alpha) {
|
||||||
|
vmain += "t = uPP * t;", vsh += "uniform mediump mat4 uPP;";
|
||||||
|
/* panini */
|
||||||
|
vmain += panini_shader();
|
||||||
|
shader_flags |= SF_ORIENT;
|
||||||
|
}
|
||||||
|
|
||||||
vmain += "gl_Position = uP * t;\n";
|
vmain += "gl_Position = uP * t;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +510,8 @@ void display_data::set_projection(int ed, ld shift) {
|
|||||||
for(int i=0; i<3; i++) NLP[3][i] = NLP[i][3] = 0;
|
for(int i=0; i<3; i++) NLP[3][i] = NLP[i][3] = 0;
|
||||||
NLP[3][3] = 1;
|
NLP[3][3] = 1;
|
||||||
}
|
}
|
||||||
glhr::projection_multiply(glhr::tmtogl_transpose(NLP));
|
if(!(shader_flags & SF_ORIENT))
|
||||||
|
glhr::projection_multiply(glhr::tmtogl_transpose(NLP));
|
||||||
}
|
}
|
||||||
if(ed) {
|
if(ed) {
|
||||||
glhr::using_eyeshift = true;
|
glhr::using_eyeshift = true;
|
||||||
@ -520,6 +546,9 @@ void display_data::set_projection(int ed, ld shift) {
|
|||||||
if(get_shader_flags() & SF_USE_ALPHA)
|
if(get_shader_flags() & SF_USE_ALPHA)
|
||||||
pp[3][2] = GLfloat(pconf.alpha);
|
pp[3][2] = GLfloat(pconf.alpha);
|
||||||
|
|
||||||
|
if(nisot::local_perspective_used())
|
||||||
|
pp = glhr::tmtogl_transpose(NLP) * pp;
|
||||||
|
|
||||||
if(get_shader_flags() & SF_ORIENT) {
|
if(get_shader_flags() & SF_ORIENT) {
|
||||||
if(GDIM == 3) for(int a=0; a<4; a++)
|
if(GDIM == 3) for(int a=0; a<4; a++)
|
||||||
models::apply_orientation_yz(pp[a][1], pp[a][2]);
|
models::apply_orientation_yz(pp[a][1], pp[a][2]);
|
||||||
@ -547,6 +576,10 @@ void display_data::set_projection(int ed, ld shift) {
|
|||||||
glhr::projection_multiply(glhr::translate(shift, 0, 0));
|
glhr::projection_multiply(glhr::translate(shift, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(in_h2xe() || in_s2xe()) {
|
||||||
|
glhr::projection_multiply(glhr::translate(0, 0, shift));
|
||||||
|
}
|
||||||
|
|
||||||
if(selected->shader_flags & SF_HALFPLANE) {
|
if(selected->shader_flags & SF_HALFPLANE) {
|
||||||
glhr::projection_multiply(glhr::translate(0, 1, 0));
|
glhr::projection_multiply(glhr::translate(0, 1, 0));
|
||||||
glhr::projection_multiply(glhr::scale(-1, 1, 1));
|
glhr::projection_multiply(glhr::scale(-1, 1, 1));
|
||||||
@ -608,7 +641,7 @@ EX void glapplymatrix(const transmatrix& V) {
|
|||||||
GLfloat mat[16];
|
GLfloat mat[16];
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
if(MDIM == 3) {
|
if(MXDIM == 3) {
|
||||||
for(int y=0; y<3; y++) {
|
for(int y=0; y<3; y++) {
|
||||||
for(int x=0; x<3; x++) mat[id++] = V[x][y];
|
for(int x=0; x<3; x++) mat[id++] = V[x][y];
|
||||||
mat[id++] = 0;
|
mat[id++] = 0;
|
||||||
|
@ -1167,8 +1167,10 @@ void movePlayer(monster *m, int delta) {
|
|||||||
|
|
||||||
cwt.at = c2; afterplayermoved();
|
cwt.at = c2; afterplayermoved();
|
||||||
if(c2->item && c2->land == laAlchemist) c2->wall = m->base->wall;
|
if(c2->item && c2->land == laAlchemist) c2->wall = m->base->wall;
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(m->base->wall == waRoundTable)
|
if(m->base->wall == waRoundTable)
|
||||||
camelot::roundTableMessage(c2);
|
camelot::roundTableMessage(c2);
|
||||||
|
#endif
|
||||||
if(c2->wall == waCloud || c2->wall == waMirror) {
|
if(c2->wall == waCloud || c2->wall == waMirror) {
|
||||||
visibleFor(500);
|
visibleFor(500);
|
||||||
cellwalker cw(c2, 0, false);
|
cellwalker cw(c2, 0, false);
|
||||||
@ -1189,7 +1191,9 @@ void movePlayer(monster *m, int delta) {
|
|||||||
items[itOrbLife] = 0;
|
items[itOrbLife] = 0;
|
||||||
m->dead = true;
|
m->dead = true;
|
||||||
}
|
}
|
||||||
|
#if CAP_COMPLEX2
|
||||||
mine::uncover_full(c2);
|
mine::uncover_full(c2);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(isWatery(c2) && isWatery(m->base) && m->inBoat)
|
if(isWatery(c2) && isWatery(m->base) && m->inBoat)
|
||||||
moveItem(m->base, c2, true);
|
moveItem(m->base, c2, true);
|
||||||
@ -2523,7 +2527,7 @@ EX void turn(int delta) {
|
|||||||
if(doall)
|
if(doall)
|
||||||
for(cell *c: currentmap->allcells()) activateMonstersAt(c);
|
for(cell *c: currentmap->allcells()) activateMonstersAt(c);
|
||||||
else
|
else
|
||||||
for(unordered_map<cell*, shiftmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++)
|
for(map<cell*, shiftmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++)
|
||||||
activateMonstersAt(it->first);
|
activateMonstersAt(it->first);
|
||||||
|
|
||||||
/* printf("size: gmatrix = %ld, active = %ld, monstersAt = %ld, delta = %d\n",
|
/* printf("size: gmatrix = %ld, active = %ld, monstersAt = %ld, delta = %d\n",
|
||||||
@ -2635,7 +2639,9 @@ EX void turn(int delta) {
|
|||||||
#if CAP_INV
|
#if CAP_INV
|
||||||
if(inv::on) inv::compute();
|
if(inv::on) inv::compute();
|
||||||
#endif
|
#endif
|
||||||
|
#if CAP_COMPLEX2
|
||||||
terracotta::check();
|
terracotta::check();
|
||||||
|
#endif
|
||||||
heat::processfires();
|
heat::processfires();
|
||||||
if(havewhat&HF_WHIRLPOOL) whirlpool::move();
|
if(havewhat&HF_WHIRLPOOL) whirlpool::move();
|
||||||
if(havewhat&HF_WHIRLWIND) whirlwind::move();
|
if(havewhat&HF_WHIRLWIND) whirlwind::move();
|
||||||
|
7
sky.cpp
7
sky.cpp
@ -55,10 +55,7 @@ void dqi_sky::draw() {
|
|||||||
|
|
||||||
int sk = get_skybrightness();
|
int sk = get_skybrightness();
|
||||||
|
|
||||||
unordered_map<cell*, pair<color_t, color_t>> colors;
|
map<cell*, pair<color_t, color_t>> colors;
|
||||||
#ifdef USE_UNORDERED_MAP
|
|
||||||
colors.reserve(isize(sky));
|
|
||||||
#endif
|
|
||||||
for(sky_item& si: sky) colors[si.c] =
|
for(sky_item& si: sky) colors[si.c] =
|
||||||
make_pair(darkena(gradient(0, si.color, 0, sk, 255), 0, 0xFF),
|
make_pair(darkena(gradient(0, si.color, 0, sk, 255), 0, 0xFF),
|
||||||
darkena(si.skycolor, 0, 0xFF)
|
darkena(si.skycolor, 0, 0xFF)
|
||||||
@ -238,6 +235,7 @@ void celldrawer::draw_ceiling() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case laVariant: {
|
case laVariant: {
|
||||||
|
#if CAP_COMPLEX2
|
||||||
int b = getBits(c);
|
int b = getBits(c);
|
||||||
col = 0x404040;
|
col = 0x404040;
|
||||||
for(int a=0; a<21; a++)
|
for(int a=0; a<21; a++)
|
||||||
@ -245,6 +243,7 @@ void celldrawer::draw_ceiling() {
|
|||||||
col += variant::features[a].color_change;
|
col += variant::features[a].color_change;
|
||||||
col = col & 0x00FF00;
|
col = col & 0x00FF00;
|
||||||
skycol = col;
|
skycol = col;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,9 @@ struct hrmap_spherical : hrmap_standard {
|
|||||||
|
|
||||||
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) {
|
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) {
|
||||||
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
|
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
|
||||||
|
#if !ISWEB
|
||||||
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
|
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
|
||||||
|
#endif
|
||||||
#if CAP_GP
|
#if CAP_GP
|
||||||
auto bak = gp::draw_li;
|
auto bak = gp::draw_li;
|
||||||
#endif
|
#endif
|
||||||
|
27
sysconfig.h
27
sysconfig.h
@ -185,6 +185,10 @@
|
|||||||
#define MAXMDIM 4
|
#define MAXMDIM 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CAP_MDIM_FIXED
|
||||||
|
#define CAP_MDIM_FIXED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_TEXTURE
|
#ifndef CAP_TEXTURE
|
||||||
#define CAP_TEXTURE (CAP_GL && (CAP_PNG || CAP_SDL_IMG) && !ISMINI)
|
#define CAP_TEXTURE (CAP_GL && (CAP_PNG || CAP_SDL_IMG) && !ISMINI)
|
||||||
#endif
|
#endif
|
||||||
@ -206,7 +210,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_TOUR
|
#ifndef CAP_TOUR
|
||||||
#define CAP_TOUR (!ISWEB && !ISMINI)
|
#define CAP_TOUR (!ISMINI)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_ROGUEVIZ
|
#ifndef CAP_ROGUEVIZ
|
||||||
@ -285,7 +289,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_SHMUP
|
#ifndef CAP_SHMUP
|
||||||
#define CAP_SHMUP 1
|
#define CAP_SHMUP (!ISWEB)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_BITFIELD
|
#ifndef CAP_BITFIELD
|
||||||
@ -403,6 +407,10 @@ extern "C" {
|
|||||||
#define CAP_GLEW (CAP_GL && !ISMOBILE && !ISMAC && !ISLINUX && !ISWEB)
|
#define CAP_GLEW (CAP_GL && !ISMOBILE && !ISMAC && !ISLINUX && !ISWEB)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ISWEB
|
||||||
|
#define GLES_ONLY
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
#if CAP_GLEW
|
#if CAP_GLEW
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
@ -462,6 +470,11 @@ typedef unsigned GLuint;
|
|||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ISWEB
|
||||||
|
#include <emscripten.h>
|
||||||
|
#include <emscripten/html5.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CAP_GMP
|
#if CAP_GMP
|
||||||
#include <gmpxx.h>
|
#include <gmpxx.h>
|
||||||
#endif
|
#endif
|
||||||
@ -478,14 +491,6 @@ typedef unsigned GLuint;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UNORDERED_MAP
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#else
|
|
||||||
#define unordered_map map
|
|
||||||
#define unordered_set set
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if ISWINDOWS
|
#if ISWINDOWS
|
||||||
@ -573,7 +578,7 @@ union SDL_Event;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_RAY
|
#ifndef CAP_RAY
|
||||||
#define CAP_RAY (MAXMDIM >= 4 && !ISWEB && !ISMOBILE && CAP_GL)
|
#define CAP_RAY (MAXMDIM >= 4 && CAP_GL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAP_MEMORY_RESERVE
|
#ifndef CAP_MEMORY_RESERVE
|
||||||
|
16
system.cpp
16
system.cpp
@ -194,7 +194,9 @@ EX void initgame() {
|
|||||||
cwt.at = currentmap->gamestart(); cwt.spin = 0; cwt.mirrored = false;
|
cwt.at = currentmap->gamestart(); cwt.spin = 0; cwt.mirrored = false;
|
||||||
cwt.at->land = firstland;
|
cwt.at->land = firstland;
|
||||||
|
|
||||||
|
#if CAP_COMPLEX2
|
||||||
if(firstland == laBrownian) brownian::init(cwt.at);
|
if(firstland == laBrownian) brownian::init(cwt.at);
|
||||||
|
#endif
|
||||||
|
|
||||||
chaosAchieved = false;
|
chaosAchieved = false;
|
||||||
|
|
||||||
@ -214,7 +216,9 @@ EX void initgame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((tactic::on || yendor::on || peace::on) && isCyclic(firstland)) {
|
if((tactic::on || yendor::on || peace::on) && isCyclic(firstland)) {
|
||||||
|
#if CAP_COMPLEX2
|
||||||
camelot::anthraxBonus = items[itHolyGrail];
|
camelot::anthraxBonus = items[itHolyGrail];
|
||||||
|
#endif
|
||||||
cwt.at->move(0)->land = firstland;
|
cwt.at->move(0)->land = firstland;
|
||||||
if(firstland == laWhirlpool) cwt.at->move(0)->wall = waSea;
|
if(firstland == laWhirlpool) cwt.at->move(0)->wall = waSea;
|
||||||
|
|
||||||
@ -366,7 +370,9 @@ EX void initgame() {
|
|||||||
#if CAP_INV
|
#if CAP_INV
|
||||||
if(inv::on) inv::init();
|
if(inv::on) inv::init();
|
||||||
#endif
|
#endif
|
||||||
|
#if CAP_COMPLEX2
|
||||||
mine::auto_teleport_charges();
|
mine::auto_teleport_charges();
|
||||||
|
#endif
|
||||||
if(!use_special_land) {
|
if(!use_special_land) {
|
||||||
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
|
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
|
||||||
}
|
}
|
||||||
@ -1265,7 +1271,9 @@ EX void stop_game() {
|
|||||||
princess::reviveAt = 0;
|
princess::reviveAt = 0;
|
||||||
princess::forceVizier = false;
|
princess::forceVizier = false;
|
||||||
princess::forceMouse = false;
|
princess::forceMouse = false;
|
||||||
|
#if CAP_COMPLEX2
|
||||||
camelot::knighted = 0;
|
camelot::knighted = 0;
|
||||||
|
#endif
|
||||||
// items[itGreenStone] = 100;
|
// items[itGreenStone] = 100;
|
||||||
clearMemory();
|
clearMemory();
|
||||||
game_active = false;
|
game_active = false;
|
||||||
@ -1287,7 +1295,6 @@ EX void set_geometry(eGeometry target) {
|
|||||||
bool was_default = pmodel == default_model();
|
bool was_default = pmodel == default_model();
|
||||||
callhooks(hooks_on_geometry_change);
|
callhooks(hooks_on_geometry_change);
|
||||||
if(geometry != target) {
|
if(geometry != target) {
|
||||||
int old_DIM = GDIM;
|
|
||||||
stop_game();
|
stop_game();
|
||||||
ors::reset();
|
ors::reset();
|
||||||
if(among(target, gProduct, gRotSpace)) {
|
if(among(target, gProduct, gRotSpace)) {
|
||||||
@ -1318,14 +1325,11 @@ EX void set_geometry(eGeometry target) {
|
|||||||
if(bt::in() || WDIM == 3 || kite::in() || arb::in()) if(!hybri) variation = eVariation::pure;
|
if(bt::in() || WDIM == 3 || kite::in() || arb::in()) if(!hybri) variation = eVariation::pure;
|
||||||
#endif
|
#endif
|
||||||
if(S3 >= OINF) variation = eVariation::pure;
|
if(S3 >= OINF) variation = eVariation::pure;
|
||||||
if(INVERSE) variation = gp::variation_for(gp::param);
|
if(INVERSE && !hybri) variation = gp::variation_for(gp::param);
|
||||||
if(ginf[target].default_variation == eVariation::pure && geometry != gArchimedean)
|
if(ginf[target].default_variation == eVariation::pure && geometry != gArchimedean)
|
||||||
variation = eVariation::pure;
|
variation = eVariation::pure;
|
||||||
if(was_default) pmodel = default_model();
|
if(was_default) pmodel = default_model();
|
||||||
if(nonisotropic && old_DIM == 2 && vid.texture_step < 4) vid.texture_step = 4;
|
|
||||||
if(WDIM == 2 && (cgflags & qIDEAL) && vid.always3 && vid.texture_step < 32) vid.texture_step = 32;
|
if(WDIM == 2 && (cgflags & qIDEAL) && vid.always3 && vid.texture_step < 32) vid.texture_step = 32;
|
||||||
if(prod) { pmodel = mdPerspective; if(vid.texture_step < 4) vid.texture_step = 4; }
|
|
||||||
if(WDIM == 3 && (cgflags & qIDEAL) && vid.texture_step < 4) vid.texture_step = 4;
|
|
||||||
if(sl2) nisot::geodesic_movement = true;
|
if(sl2) nisot::geodesic_movement = true;
|
||||||
|
|
||||||
if(rotspace) {
|
if(rotspace) {
|
||||||
@ -1495,7 +1499,9 @@ EX void start_game() {
|
|||||||
ignored_memory_warning = false;
|
ignored_memory_warning = false;
|
||||||
check_cgi();
|
check_cgi();
|
||||||
cgi.require_basics();
|
cgi.require_basics();
|
||||||
|
#if CAP_ARCM
|
||||||
arcm::current.compute_geometry();
|
arcm::current.compute_geometry();
|
||||||
|
#endif
|
||||||
initcells();
|
initcells();
|
||||||
expansion.reset();
|
expansion.reset();
|
||||||
|
|
||||||
|
7
tour.cpp
7
tour.cpp
@ -7,6 +7,13 @@
|
|||||||
|
|
||||||
#include "hyper.h"
|
#include "hyper.h"
|
||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
|
#if !CAP_TOUR
|
||||||
|
EX namespace tour {
|
||||||
|
EX always_false on;
|
||||||
|
EX }
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CAP_TOUR
|
#if CAP_TOUR
|
||||||
|
|
||||||
/** \brief Variables and function related to Guided Tour and other presentations. */
|
/** \brief Variables and function related to Guided Tour and other presentations. */
|
||||||
|
3
util.cpp
3
util.cpp
@ -263,6 +263,7 @@ cld exp_parser::parse(int prio) {
|
|||||||
force_eat(")");
|
force_eat(")");
|
||||||
res = edge_of_triangle_with_angles(M_PI/2, M_PI/a, M_PI/b);
|
res = edge_of_triangle_with_angles(M_PI/2, M_PI/a, M_PI/b);
|
||||||
}
|
}
|
||||||
|
#if CAP_ARCM
|
||||||
else if(eat("arcmedge(")) {
|
else if(eat("arcmedge(")) {
|
||||||
vector<int> vals;
|
vector<int> vals;
|
||||||
vals.push_back(iparse(0));
|
vals.push_back(iparse(0));
|
||||||
@ -280,6 +281,7 @@ cld exp_parser::parse(int prio) {
|
|||||||
if(extra_params.count("distunit"))
|
if(extra_params.count("distunit"))
|
||||||
res /= extra_params["distunit"];
|
res /= extra_params["distunit"];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if(eat("regangle(")) {
|
else if(eat("regangle(")) {
|
||||||
cld edgelen = parse(0);
|
cld edgelen = parse(0);
|
||||||
if(extra_params.count("distunit")) {
|
if(extra_params.count("distunit")) {
|
||||||
@ -373,6 +375,7 @@ cld exp_parser::parse(int prio) {
|
|||||||
else if(number == "psl_steps") res = cgi.psl_steps;
|
else if(number == "psl_steps") res = cgi.psl_steps;
|
||||||
else if(number == "single_step") res = cgi.single_step;
|
else if(number == "single_step") res = cgi.single_step;
|
||||||
else if(number == "step") res = hdist0(tC0(currentmap->adj(cwt.at, 0)));
|
else if(number == "step") res = hdist0(tC0(currentmap->adj(cwt.at, 0)));
|
||||||
|
else if(number == "edgelen") res = hdist(get_corner_position(cwt.at, 0), get_corner_position(cwt.at, 1));
|
||||||
else if(number == "mousey") res = mousey;
|
else if(number == "mousey") res = mousey;
|
||||||
else if(number == "random") res = randd();
|
else if(number == "random") res = randd();
|
||||||
else if(number == "mousez") res = cld(mousex - current_display->xcenter, mousey - current_display->ycenter) / cld(current_display->radius, 0);
|
else if(number == "mousez") res = cld(mousex - current_display->xcenter, mousey - current_display->ycenter) / cld(current_display->radius, 0);
|
||||||
|
@ -1063,7 +1063,11 @@ void save_mode_data(hstream& f) {
|
|||||||
f.write<char>(chaosmode);
|
f.write<char>(chaosmode);
|
||||||
f.write<char>(shmup::on);
|
f.write<char>(shmup::on);
|
||||||
f.write<char>(inv::on);
|
f.write<char>(inv::on);
|
||||||
|
#if CAP_TOUR
|
||||||
f.write<char>(tour::on);
|
f.write<char>(tour::on);
|
||||||
|
#else
|
||||||
|
f.write<char>(false);
|
||||||
|
#endif
|
||||||
f.write<char>(peace::on);
|
f.write<char>(peace::on);
|
||||||
f.write<char>(peace::otherpuzzles);
|
f.write<char>(peace::otherpuzzles);
|
||||||
f.write<char>(peace::explore_other);
|
f.write<char>(peace::explore_other);
|
||||||
|
Loading…
Reference in New Issue
Block a user