mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-22 14:00:13 +00:00
removed the MAX_EDGE limit
This commit is contained in:
parent
a6da5ded75
commit
2271a67506
@ -51,9 +51,11 @@ struct archimedean_tiling {
|
||||
|
||||
vector<ld> inradius, circumradius, alphas;
|
||||
|
||||
int matches[30][30];
|
||||
int periods[30];
|
||||
int tilegroup[30], groupoffset[30], tilegroups;
|
||||
vector<vector<int>> matches;
|
||||
vector<int> periods;
|
||||
vector<int> tilegroup;
|
||||
vector<int> groupoffset;
|
||||
int tilegroups;
|
||||
|
||||
int errors;
|
||||
string errormsg;
|
||||
@ -130,18 +132,21 @@ void archimedean_tiling::make_match(int a, int i, int b, int j) {
|
||||
periods[a] = periods[b] = gcd(matches[a][b] - (j-i), periods[a]);
|
||||
}
|
||||
|
||||
/** mostly to protect the user from entering too large numbers */
|
||||
const int MAX_EDGE_ARCM = FULL_EDGE;
|
||||
|
||||
void archimedean_tiling::prepare() {
|
||||
|
||||
euclidean_angle_sum = 0;
|
||||
for(int f: faces) euclidean_angle_sum += (f-2.) / f;
|
||||
|
||||
for(int i: faces) if(i > MAX_EDGE) {
|
||||
errormsg = XLAT("currently no more than %1 edges", its(MAX_EDGE));
|
||||
for(int i: faces) if(i > MAX_EDGE_ARCM) {
|
||||
errormsg = XLAT("currently no more than %1 edges", its(MAX_EDGE_ARCM));
|
||||
errors++;
|
||||
return;
|
||||
}
|
||||
if(isize(faces) > MAX_EDGE/2) {
|
||||
errormsg = XLAT("currently no more than %1 faces in vertex", its(MAX_EDGE/2));
|
||||
if(isize(faces) > MAX_EDGE_ARCM/2) {
|
||||
errormsg = XLAT("currently no more than %1 faces in vertex", its(MAX_EDGE_ARCM/2));
|
||||
errors++;
|
||||
return;
|
||||
}
|
||||
@ -192,8 +197,13 @@ void archimedean_tiling::prepare() {
|
||||
have_symmetry = false;
|
||||
for(int i=0; i<N; i++) if(invert[i]) have_symmetry = true;
|
||||
|
||||
for(int i=0; i<M; i++) for(int j=0; j<M; j++) matches[i][j] = i==j ? 0 : -1;
|
||||
matches.resize(M);
|
||||
for(int i=0; i<M; i++) {
|
||||
matches[i].resize(M);
|
||||
for(int j=0; j<M; j++) matches[i][j] = i==j ? 0 : -1;
|
||||
}
|
||||
|
||||
periods.resize(M);
|
||||
for(int i=0; i<M; i++) periods[i] = i<2*N ? faces[i/2] : N;
|
||||
|
||||
for(int i=0; i<N; i++) {
|
||||
@ -289,7 +299,9 @@ void archimedean_tiling::regroup() {
|
||||
make_match(i, 0, k, matches[i][j] + matches[j][k]);
|
||||
make_match(i, 0, k, matches[i][j] + matches[j][k] + gcd(periods[i], periods[j]));
|
||||
}
|
||||
for(int i=0; i<M; i++) tilegroup[i] = -1;
|
||||
tilegroup.clear();
|
||||
tilegroup.resize(M, -1);
|
||||
groupoffset.resize(M);
|
||||
tilegroups = 0;
|
||||
for(int i=0; i<M; i+=(have_symmetry?1:2)) if(tilegroup[i] == -1) {
|
||||
if(periods[i] < 0) periods[i] = -periods[i];
|
||||
@ -335,11 +347,13 @@ void archimedean_tiling::compute_geometry() {
|
||||
dynamicval<eGeometry> dv(geometry, gArchimedean);
|
||||
|
||||
/* compute the geometry */
|
||||
inradius.resize(N);
|
||||
inradius.resize(N+1); inradius[N] = 0;
|
||||
circumradius.resize(N);
|
||||
alphas.resize(N);
|
||||
ld elmin = 0, elmax = hyperbolic ? 10 : sphere ? M_PI : 1;
|
||||
|
||||
/* inradius[N] is used in farcorner and nearcorner. Probably a bug */
|
||||
|
||||
if(real_faces == 2) {
|
||||
/* standard methods fail for dihedra, but the answer is easy */
|
||||
edgelength = 2 * M_PI / faces[0];
|
||||
@ -777,19 +791,19 @@ void fixup_matrix(transmatrix& T, const transmatrix& X, ld step) {
|
||||
}
|
||||
|
||||
pair<ld, ld>& archimedean_tiling::get_triangle(heptagon *h, int cid) {
|
||||
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||
return triangles[id_of(h)][gmod(parent_index_of(h) + cid, neighbors_of(h))];
|
||||
}
|
||||
|
||||
pair<int, int>& archimedean_tiling::get_adj(heptagon *h, int cid) {
|
||||
return adjacent[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||
return adjacent[id_of(h)][gmod(parent_index_of(h) + cid, neighbors_of(h))];
|
||||
}
|
||||
|
||||
pair<int, int>& archimedean_tiling::get_adj(const pair<int, int>& p, int delta) {
|
||||
return adjacent[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])];
|
||||
return adjacent[p.first][gmod(p.second + delta, isize(adjacent[p.first]))];
|
||||
}
|
||||
|
||||
pair<ld, ld>& archimedean_tiling::get_triangle(const pair<int, int>& p, int delta) {
|
||||
return triangles[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])];
|
||||
return triangles[p.first][gmod(p.second + delta, isize(adjacent[p.first]))];
|
||||
}
|
||||
|
||||
transmatrix adjcell_matrix(heptagon *h, int d) {
|
||||
|
@ -841,9 +841,7 @@ EX bool buildBarrierNowall(cell *c, eLand l2, int forced_dir IS(NODIR)) {
|
||||
bool warpv = warped_version(c->land, l2);
|
||||
if(warpv && !arcm::in() && !pseudohept(c)) return false;
|
||||
|
||||
int ds[MAX_EDGE];
|
||||
for(int i=0; i<c->type; i++) ds[i] = i;
|
||||
for(int j=0; j<c->type; j++) swap(ds[j], ds[hrand(j+1)]);
|
||||
vector<int> ds = hrandom_permutation(c->type);
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
int d = forced_dir != NODIR ? forced_dir : (valence()>3) ? (2+(i&1)) : ds[i];
|
||||
|
38
bigstuff.cpp
38
bigstuff.cpp
@ -298,32 +298,32 @@ EX void generateTreasureIsland(cell *c) {
|
||||
beCIsland(c);
|
||||
if(c->wall == waCTree) return;
|
||||
}
|
||||
cell* ctab[MAX_EDGE];
|
||||
int qc = 0, qlo, qhi;
|
||||
vector<cell*> ctab;
|
||||
int qlo, qhi;
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cell *c2 = createMov(c, i);
|
||||
if(!eubinary) currentmap->generateAlts(c2->master);
|
||||
if((eubinary || (c->master->alt && c2->master->alt)) && celldistAlt(c2) < celldistAlt(c)) {
|
||||
ctab[qc++] = c2;
|
||||
ctab.push_back(c2);
|
||||
qlo = i; qhi = i;
|
||||
while(true && qc < MAX_EDGE) {
|
||||
while(true && isize(ctab) < c->type) {
|
||||
qlo--;
|
||||
c2 = c->cmodmove(qlo);
|
||||
if(!eubinary && !c2->master->alt) break;
|
||||
if(celldistAlt(c2) >= celldistAlt(c)) break;
|
||||
ctab[qc++] = c2;
|
||||
ctab.push_back(c2);
|
||||
}
|
||||
while(true && qc < MAX_EDGE) {
|
||||
while(true && isize(ctab) < c->type) {
|
||||
qhi++;
|
||||
c2 = c->cmodmove(qhi);
|
||||
if(!eubinary && !c2->master->alt) break;
|
||||
if(celldistAlt(c2) >= celldistAlt(c)) break;
|
||||
ctab[qc++] = c2;
|
||||
ctab.push_back(c2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!qc) {
|
||||
if(ctab.empty()) {
|
||||
printf("NO QC\n"); c->wall = waSea;
|
||||
for(int i=0; i<c->type; i++) printf("%d ", celldistAlt(c->move(i)));
|
||||
printf("vs %d\n", celldistAlt(c));
|
||||
@ -338,9 +338,9 @@ EX void generateTreasureIsland(cell *c) {
|
||||
}
|
||||
if(src && c2->wall == waCTree && (eubinary||c->master->alt) && celldistAlt(c) <= -10 && geometry != gRhombic3) {
|
||||
bool end = true;
|
||||
for(int i=0; i<qc; i++) {
|
||||
generateTreasureIsland(ctab[i]);
|
||||
if(ctab[i]->wall != waCTree)
|
||||
for(cell *cc: ctab) {
|
||||
generateTreasureIsland(cc);
|
||||
if(cc->wall != waCTree)
|
||||
end = false;
|
||||
}
|
||||
// printf("%p: end=%d, qc=%d, dist=%d\n", c, end, qc, celldistAlt(c));
|
||||
@ -571,8 +571,8 @@ EX void buildEquidistant(cell *c) {
|
||||
// if(qcv != 1) { printf("qcv = %d\n", qcv); exit(1); }
|
||||
cell *c2 = c->move(sid);
|
||||
int bsid = c->c.spin(sid);
|
||||
for(int j=0; j<7; j++) {
|
||||
int q = (bsid+j+42) % c2->type;
|
||||
for(int j=0; j<c2->type; j++) {
|
||||
int q = gmod(bsid+j, c2->type);
|
||||
cell *c3 = c2->move(q);
|
||||
if(coastval(c3, b) < mcv) {
|
||||
cell *c4 = c2->cmodmove(bsid+1);
|
||||
@ -581,7 +581,7 @@ EX void buildEquidistant(cell *c) {
|
||||
mcv2 = coastval(c4, b);
|
||||
break;
|
||||
}
|
||||
q = (bsid-j+MODFIXER) % c2->type;
|
||||
q = gmod(bsid-j, c2->type);
|
||||
c3 = c2->move(q);
|
||||
if(coastval(c3, b) < mcv) {
|
||||
cell *c4 = c2->cmodmove(bsid-1);
|
||||
@ -774,14 +774,12 @@ EX void buildEquidistant(cell *c) {
|
||||
}
|
||||
|
||||
EX cell *randomDown(cell *c) {
|
||||
cell *tab[MAX_EDGE];
|
||||
int q=0;
|
||||
vector<cell*> tab;
|
||||
for(int i=0; i<c->type; i++)
|
||||
if(c->move(i) && coastval(c->move(i), laIvoryTower) < coastval(c, laIvoryTower))
|
||||
tab[q++] = c->move(i);
|
||||
if(!q) return NULL;
|
||||
if(q==1) return tab[0];
|
||||
return tab[hrand(q)];
|
||||
tab.push_back(c->move(i));
|
||||
if(isize(tab)==1) return tab[0];
|
||||
return hrand_elt(tab, (cell*)nullptr);
|
||||
}
|
||||
|
||||
EX int edgeDepth(cell *c) {
|
||||
|
@ -28,7 +28,7 @@ struct blizzardcell {
|
||||
transmatrix *gm;
|
||||
char wmap;
|
||||
int inward, outward, ward;
|
||||
int qty[MAX_EDGE];
|
||||
vector<int> qty;
|
||||
vector<snowball*> inorder, outorder;
|
||||
int inid, outid;
|
||||
~blizzardcell() { for(auto i: inorder) delete i; }
|
||||
@ -77,6 +77,7 @@ EX void drawBlizzards() {
|
||||
auto& bc = *bcells[i];
|
||||
cell *c = bc.c;
|
||||
bc.inward = bc.outward = 0;
|
||||
bc.qty.resize(c->type);
|
||||
for(int i=0; i<c->type; i++) {
|
||||
int& qty = bc.qty[i];
|
||||
qty = 0;
|
||||
|
@ -858,7 +858,10 @@ void celldrawer::draw_halfvine() {
|
||||
queuepolyat(GDIM == 2 ? Vdepth : V2, cgi.shSemiFloor[0], darkena(vcol, fd, 0xFF), PPR::WALL3A);
|
||||
{dynamicval<color_t> p(poly_outline, OUTLINE_TRANS); queuepolyat(V2 * spin(M_PI*2/3), cgi.shSemiFloorShadow, SHADOW_WALL, GDIM == 2 ? PPR::WALLSHADOW : PPR::TRANSPARENT_SHADOW); }
|
||||
auto& side = queuepolyat(V2, cgi.shSemiFloorSide[SIDE_WALL], darkena(vcol, fd, 0xFF), PPR::WALL3A-2+away(V2));
|
||||
if(GDIM == 3 && qfi.fshape) side.tinf = &floor_texture_vertices[shar.id];
|
||||
if(GDIM == 3 && qfi.fshape) {
|
||||
side.tinf = &floor_texture_vertices[shar.id];
|
||||
ensure_vertex_number(*side.tinf, side.cnt);
|
||||
}
|
||||
|
||||
if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, j, c) {
|
||||
int dis = i-j;
|
||||
@ -1570,6 +1573,7 @@ void celldrawer::draw_features_and_walls_3d() {
|
||||
#endif
|
||||
{
|
||||
poly.tinf = &floor_texture_vertices[qfi.fshape->id];
|
||||
ensure_vertex_number(*poly.tinf, poly.cnt);
|
||||
poly.offset_texture = 0;
|
||||
}
|
||||
}
|
||||
@ -1813,7 +1817,7 @@ void celldrawer::draw_cellstat() {
|
||||
|
||||
auto si = patterns::getpatterninfo0(c);
|
||||
|
||||
for(int i=(si.dir + MODFIXER) % si.symmetries; i<c->type; i += si.symmetries) {
|
||||
for(int i= gmod(si.dir, si.symmetries); i<c->type; i += si.symmetries) {
|
||||
queuepoly(V * ddspin(c, i) * (si.reflect?Mirror:Id), cgi.shAsymmetric, darkena(0x000000, 0, 0xC0));
|
||||
si.dir += si.symmetries;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ EX eMonster who_kills_me;
|
||||
|
||||
EX int lastkills;
|
||||
|
||||
EX bool legalmoves[MAX_EDGE+1];
|
||||
EX vector<bool> legalmoves;
|
||||
|
||||
EX bool hasSafeOrb(cell *c) {
|
||||
return
|
||||
@ -402,11 +402,11 @@ EX void checkmove() {
|
||||
// do not activate orbs!
|
||||
for(int i=0; i<ittypes; i++) orbusedbak[i] = orbused[i];
|
||||
|
||||
for(int i=0; i<=MAX_EDGE; i++) legalmoves[i] = false;
|
||||
legalmoves.clear(); legalmoves.resize(cwt.at->type+1, false);
|
||||
|
||||
canmove = haveRangedTarget();
|
||||
items[itWarning]+=2;
|
||||
if(movepcto(-1, 0, true)) canmove = legalmoves[MAX_EDGE] = true;
|
||||
if(movepcto(-1, 0, true)) canmove = legalmoves[cwt.at->type] = true;
|
||||
|
||||
if(vid.mobilecompasssize || !canmove)
|
||||
for(int i=0; i<cwt.at->type; i++)
|
||||
|
19
complex.cpp
19
complex.cpp
@ -64,7 +64,7 @@ EX namespace whirlwind {
|
||||
qdirs = 0;
|
||||
if(d == 0) return;
|
||||
int qdf = 0, qdt = 0;
|
||||
int cats[MAX_EDGE];
|
||||
vector<int> cats(c->type);
|
||||
for(int i=0; i<c->type; i++)
|
||||
cats[i] = cat(createMov(c,i));
|
||||
for(int i=0; i<c->type; i++)
|
||||
@ -2923,11 +2923,10 @@ EX namespace kraken {
|
||||
for(int i=0; i<isize(dcal); i++) {
|
||||
cell *c = dcal[i];
|
||||
if(c->monst == moKrakenH && !c->stuntime && !isWateryOrBoat(c)) {
|
||||
int qdir = 0;
|
||||
cell *ctab[MAX_EDGE];
|
||||
forCellEx(c2, c) if(isWatery(c2)) ctab[qdir++] = c2;
|
||||
hrandom_shuffle(ctab, qdir);
|
||||
while(qdir--) trymove(ctab[qdir]);
|
||||
vector<cell*> ctab;
|
||||
forCellEx(c2, c) if(isWatery(c2)) ctab.push_back(c2);
|
||||
hrandom_shuffle(ctab);
|
||||
for(auto& cc: ctab) trymove(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4052,14 +4051,6 @@ EX namespace dungeon {
|
||||
}
|
||||
|
||||
if(c->wparam) {
|
||||
/* int q = 0;
|
||||
cell* downs[MAX_EDGE];
|
||||
forCellEx(c2, c) {
|
||||
buildEquidistant(c2);
|
||||
if(coastvalEdge(c2) > coastvalEdge(c)) downs[q++] = c2;
|
||||
}
|
||||
if(q) downs[hrand(q)]->wall = waLadder;
|
||||
*/
|
||||
cell *c2 =
|
||||
WDIM == 3 ? random_child(c, coastvalEdge) :
|
||||
c->wparam == 1 ? ts::add(c, 1, 2, coastvalEdge) :
|
||||
|
@ -83,7 +83,7 @@ EX movedir vectodir(hyperpoint P) {
|
||||
|
||||
ld binv = 99;
|
||||
|
||||
ld dirdist[MAX_EDGE];
|
||||
vector<ld> dirdist(cwt.at->type);
|
||||
|
||||
for(int i=0; i<cwt.at->type; i++) {
|
||||
transmatrix T = currentmap->adj(cwt.at, (cwt + i).spin);
|
||||
@ -139,7 +139,7 @@ EX void calcMousedest() {
|
||||
|
||||
cellwalker bcwt = cwt;
|
||||
|
||||
ld dists[MAX_EDGE];
|
||||
vector<ld> dists(cwt.at->type);
|
||||
|
||||
transmatrix U = ggmatrix(cwt.at);
|
||||
|
||||
|
14
crystal.cpp
14
crystal.cpp
@ -13,6 +13,7 @@ EX namespace crystal {
|
||||
|
||||
#if HDR
|
||||
static const int MAXDIM = 7;
|
||||
static const int MAX_EDGE_CRYSTAL = 2 * MAXDIM;
|
||||
|
||||
struct coord : public array<int, MAXDIM> {
|
||||
coord operator + (coord b) { for(int i=0; i<MAXDIM; i++) b[i] += self[i]; return b; }
|
||||
@ -279,7 +280,7 @@ struct crystal_structure {
|
||||
if(count_bugs()) {
|
||||
printf("bugs found\n");
|
||||
}
|
||||
if(dir > MAX_EDGE || dim > MAXDIM) {
|
||||
if(dir > MAX_EDGE_CRYSTAL || dim > MAXDIM) {
|
||||
printf("Dimension or directions exceeded -- I have generated it, but won't play");
|
||||
exit(0);
|
||||
}
|
||||
@ -722,7 +723,7 @@ bool is_bi(crystal_structure& cs, coord co) {
|
||||
return false;
|
||||
}
|
||||
|
||||
array<array<int,2>, MAX_EDGE> distlimit_table = {{
|
||||
array<array<int,2>, MAX_EDGE_CRYSTAL> distlimit_table = {{
|
||||
{{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{SEE_ALL,SEE_ALL}}, {{15, 10}},
|
||||
{{6, 4}}, {{5, 3}}, {{4, 3}}, {{4, 3}}, {{3, 2}}, {{3, 2}}, {{3, 2}}, {{3, 2}}, {{3, 2}}
|
||||
}};
|
||||
@ -1257,7 +1258,7 @@ EX void build_rugdata() {
|
||||
const transmatrix& V = gp.second;
|
||||
|
||||
auto co = m->get_coord(c);
|
||||
ldcoord vcoord[MAX_EDGE];
|
||||
vector<ldcoord> vcoord(c->type);
|
||||
|
||||
for(int i=0; i<c->type; i++)
|
||||
if(valence() == 4)
|
||||
@ -1270,7 +1271,7 @@ EX void build_rugdata() {
|
||||
v->flat = coord_to_flat(co);
|
||||
v->valid = true;
|
||||
|
||||
rugpoint *p[MAX_EDGE];
|
||||
rugpoint *p[MAX_EDGE_CRYSTAL];
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
p[i] = addRugpoint(V * get_corner_position(c, i), 0);
|
||||
@ -1284,7 +1285,7 @@ EX void build_rugdata() {
|
||||
else {
|
||||
hyperpoint hco = coord_to_flat(co, 4);
|
||||
hco[3] -= cut_level * rug::modelscale;
|
||||
hyperpoint vco[MAX_EDGE];
|
||||
vector<hyperpoint> vco(c->type);
|
||||
for(int i=0; i<c->type; i++) {
|
||||
vco[i] = coord_to_flat(vcoord[i], 4);
|
||||
vco[i][3] -= cut_level * rug::modelscale;
|
||||
@ -1325,8 +1326,7 @@ EX void set_crystal(int sides) {
|
||||
static char buf[20];
|
||||
sprintf(buf, "{%d,4}", sides);
|
||||
ginf[gCrystal].tiling_name = buf;
|
||||
if(sides < MAX_EDGE)
|
||||
ginf[gCrystal].distlimit = distlimit_table[sides];
|
||||
ginf[gCrystal].distlimit = distlimit_table[min(sides, MAX_EDGE_CRYSTAL-1)];
|
||||
}
|
||||
|
||||
void test_crt() {
|
||||
|
@ -557,7 +557,7 @@ EX void moverefresh(bool turn IS(true)) {
|
||||
c->monst = moReptile;
|
||||
c->hitpoints = 3;
|
||||
c->stuntime = 0;
|
||||
int gooddirs[MAX_EDGE], qdirs = 0;
|
||||
vector<int> gooddirs;
|
||||
// in the peace mode, a reptile will
|
||||
// prefer to walk on the ground, rather than the chasm
|
||||
for(int i=0; i<c->type; i++) {
|
||||
@ -565,9 +565,9 @@ EX void moverefresh(bool turn IS(true)) {
|
||||
int i1 = (i+c->type-3) % c->type;
|
||||
if(c->move(i0) && passable(c->move(i0), c, 0))
|
||||
if(c->move(i1) && passable(c->move(i1), c, 0))
|
||||
gooddirs[qdirs++] = i;
|
||||
gooddirs.push_back(i);
|
||||
}
|
||||
if(qdirs) c->mondir = gooddirs[hrand(qdirs)];
|
||||
c->mondir = hrand_elt(gooddirs, c->mondir);
|
||||
playSound(c, "click");
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ void geometry_information::init_floorshapes() {
|
||||
for(auto sh: all_escher_floorshapes) sh->id = ids++;
|
||||
}
|
||||
|
||||
typedef pair<transmatrix, array<transmatrix, MAX_EDGE>> matrixitem;
|
||||
typedef pair<transmatrix, vector<transmatrix>> matrixitem;
|
||||
|
||||
struct mesher {
|
||||
eGeometry g;
|
||||
@ -119,6 +119,7 @@ struct matrixlist {
|
||||
matrixitem genitem(const transmatrix& m1, const transmatrix& m2, int nsym) {
|
||||
matrixitem mi;
|
||||
mi.first = m1;
|
||||
mi.second.resize(nsym);
|
||||
for(int i=0; i<nsym; i++)
|
||||
mi.second[i] = spin(2*M_PI*i/nsym) * m2;
|
||||
return mi;
|
||||
@ -281,6 +282,7 @@ void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, ld
|
||||
}
|
||||
|
||||
for(int k=0; k<SIDEPARS; k++) {
|
||||
fsh.gpside[k].resize(c->type);
|
||||
for(int i=0; i<c->type; i++) {
|
||||
sizeto(fsh.gpside[k][i], id);
|
||||
bshape(fsh.gpside[k][i][id], PPR::LAKEWALL);
|
||||
@ -435,7 +437,8 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
for(int i=0; i<=cor; i++)
|
||||
hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL));
|
||||
|
||||
for(int k=0; k<SIDEPARS; k++)
|
||||
for(int k=0; k<SIDEPARS; k++) {
|
||||
fsh.gpside[k].resize(cor);
|
||||
for(int cid=0; cid<cor; cid++) {
|
||||
sizeto(fsh.gpside[k][cid], id);
|
||||
bshape(fsh.gpside[k][cid][id], fsh.prio);
|
||||
@ -443,6 +446,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
hpcpush(iddspin(c, cid) * cornerlist[(cid+1)%cor]);
|
||||
chasmifyPoly(dlow_table[k], dhi_table[k], k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto pfsh: all_escher_floorshapes) {
|
||||
@ -481,6 +485,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
m.n.sym = cor;
|
||||
|
||||
int v = sidir+siid;
|
||||
for(auto& mvi: m.v) mvi.second.resize(cor);
|
||||
|
||||
for(int ii=0; ii<2; ii++) {
|
||||
int i = 0;
|
||||
@ -545,6 +550,9 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
texture_order([&] (ld x, ld y) { hpcpush(orthogonal_move(normalize(C0 + v1 * x + v2 * y), dfloor_table[k])); });
|
||||
}
|
||||
}
|
||||
|
||||
finishshape();
|
||||
ensure_vertex_number(*last);
|
||||
}
|
||||
|
||||
for(int co=0; co<2; co++) {
|
||||
@ -574,12 +582,21 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
texture_order([&] (ld x, ld y) { hpcpush(orthogonal_move(normalize(C0 + v1 * x + v2 * y), top + h * (x+y))); });
|
||||
}
|
||||
}
|
||||
|
||||
finishshape();
|
||||
ensure_vertex_number(*last);
|
||||
}
|
||||
|
||||
for(int l=0; l<SIDEPARS; l++) {
|
||||
for(auto& li: fsh.side[l]) li.tinf = &floor_texture_vertices[fsh.id];
|
||||
for(int e=0; e<MAX_EDGE; e++)
|
||||
for(auto& li: fsh.gpside[l][e]) li.tinf = &floor_texture_vertices[fsh.id];
|
||||
for(auto& li: fsh.side[l]) {
|
||||
li.tinf = &floor_texture_vertices[fsh.id];
|
||||
ensure_vertex_number(li);
|
||||
}
|
||||
for(auto& gs: fsh.gpside[l])
|
||||
for(auto& li: gs) {
|
||||
li.tinf = &floor_texture_vertices[fsh.id];
|
||||
ensure_vertex_number(li);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,7 +609,8 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
|
||||
for(auto& li: fsh.levels[l]) li.tinf = &floor_texture_vertices[fsh.id];
|
||||
fsh.side[l] = shFullFloor.side[l];
|
||||
for(auto& li: fsh.side[l]) li.tinf = &floor_texture_vertices[fsh.id];
|
||||
for(int e=0; e<MAX_EDGE; e++) {
|
||||
fsh.gpside[l].resize(c->type);
|
||||
for(int e=0; e<c->type; e++) {
|
||||
fsh.gpside[l][e] = shFullFloor.gpside[l][e];
|
||||
for(auto& li: fsh.gpside[l][e]) li.tinf = &floor_texture_vertices[fsh.id];
|
||||
}
|
||||
@ -1016,16 +1034,28 @@ void draw_shape_for_texture(floorshape* sh) {
|
||||
}
|
||||
|
||||
// SL2 needs 6 times more
|
||||
for(int a=0; a<MAX_EDGE*6; a++)
|
||||
texture_order([&] (ld x, ld y) {
|
||||
hyperpoint h = center + v1 * x + v2 * y;
|
||||
hyperpoint inmodel;
|
||||
applymodel(h, inmodel);
|
||||
glvec2 v;
|
||||
v[0] = (1 + inmodel[0] * vid.scale) / 2;
|
||||
v[1] = (1 - inmodel[1] * vid.scale) / 2;
|
||||
ftv.tvertices.push_back(glhr::makevertex(v[0], v[1], 0));
|
||||
});
|
||||
texture_order([&] (ld x, ld y) {
|
||||
hyperpoint h = center + v1 * x + v2 * y;
|
||||
hyperpoint inmodel;
|
||||
applymodel(h, inmodel);
|
||||
glvec2 v;
|
||||
v[0] = (1 + inmodel[0] * vid.scale) / 2;
|
||||
v[1] = (1 - inmodel[1] * vid.scale) / 2;
|
||||
ftv.tvertices.push_back(glhr::makevertex(v[0], v[1], 0));
|
||||
});
|
||||
}
|
||||
|
||||
/** copy the texture vertices so that there are at least qty of them */
|
||||
EX void ensure_vertex_number(basic_textureinfo& bti, int qty) {
|
||||
int s = isize(bti.tvertices);
|
||||
while(isize(bti.tvertices) <= qty) {
|
||||
for(int i=0; i<s; i++) bti.tvertices.push_back(bti.tvertices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** ensure_vertex_number for a hpcshape */
|
||||
EX void ensure_vertex_number(hpcshape& sh) {
|
||||
ensure_vertex_number(*sh.tinf, sh.e - sh.s);
|
||||
}
|
||||
|
||||
const int FLOORTEXTURESIZE = 4096;
|
||||
|
13
game.cpp
13
game.cpp
@ -43,8 +43,21 @@ EX int hrand(int i) {
|
||||
#if HDR
|
||||
template<class T, class... U> T pick(T x, U... u) { std::initializer_list<T> i = {x,u...}; return *(i.begin() + hrand(1+sizeof...(u))); }
|
||||
template<class T> void hrandom_shuffle(T* x, int n) { for(int k=1; k<n; k++) swap(x[k], x[hrand(k+1)]); }
|
||||
template<class T> void hrandom_shuffle(T& container) { hrandom_shuffle(&container[0], isize(container)); }
|
||||
template<class U> auto hrand_elt(U& container) -> decltype(container[0]) { return container[hrand(isize(container))]; }
|
||||
template<class T, class U> T hrand_elt(U& container, T default_value) {
|
||||
if(container.empty()) return default_value;
|
||||
return container[hrand(isize(container))];
|
||||
}
|
||||
#endif
|
||||
|
||||
EX vector<int> hrandom_permutation(int qty) {
|
||||
vector<int> res(qty);
|
||||
for(int i=0; i<qty; i++) res[i] = i;
|
||||
hrandom_shuffle(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Use \link hrngen \endlink to generate a floating point number between 0 and 1.
|
||||
*/
|
||||
|
||||
|
12
geometry.cpp
12
geometry.cpp
@ -63,7 +63,8 @@ struct floorshape {
|
||||
int pstrength; // pattern strength in 3D
|
||||
int fstrength; // frame strength in 3D
|
||||
PPR prio;
|
||||
vector<hpcshape> b, shadow, side[SIDEPARS], gpside[SIDEPARS][MAX_EDGE], levels[SIDEPARS], cone[2];
|
||||
vector<hpcshape> b, shadow, side[SIDEPARS], levels[SIDEPARS], cone[2];
|
||||
vector<vector<hpcshape>> gpside[SIDEPARS];
|
||||
floorshape() { prio = PPR::FLOOR; pstrength = fstrength = 10; }
|
||||
};
|
||||
|
||||
@ -112,8 +113,7 @@ struct geometry_information {
|
||||
/** distance from heptagon center to heptagon vertex (either hexf or hcrossf) */
|
||||
ld rhexf;
|
||||
|
||||
transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
|
||||
transmatrix invhexmove[MAX_EDGE];
|
||||
vector<transmatrix> heptmove, hexmove, invhexmove;
|
||||
|
||||
int base_distlimit;
|
||||
|
||||
@ -381,7 +381,7 @@ hpcshape
|
||||
/* Goldberg parameters */
|
||||
#if CAP_GP
|
||||
struct gpdata_t {
|
||||
transmatrix Tf[MAX_EDGE][32][32][6];
|
||||
vector<array<array<array<transmatrix, 6>, 32>, 32>> Tf;
|
||||
transmatrix corners;
|
||||
ld alpha;
|
||||
int area;
|
||||
@ -478,6 +478,10 @@ void geometry_information::prepare_basics() {
|
||||
|
||||
finish:
|
||||
|
||||
heptmove.resize(S7);
|
||||
hexmove.resize(S7);
|
||||
invhexmove.resize(S7);
|
||||
|
||||
for(int d=0; d<S7; d++)
|
||||
heptmove[d] = spin(-d * ALPHA) * xpush(tessf) * spin(M_PI);
|
||||
|
||||
|
@ -85,7 +85,7 @@ EX namespace gp {
|
||||
transmatrix adjm;
|
||||
};
|
||||
|
||||
EX int fixg6(int x) { return (x + MODFIXER) % SG6; }
|
||||
EX int fixg6(int x) { return gmod(x, SG6); }
|
||||
|
||||
EX int get_code(const local_info& li) {
|
||||
return
|
||||
@ -137,7 +137,7 @@ EX namespace gp {
|
||||
|
||||
EX int pseudohept_val(cell *c) {
|
||||
loc v = get_coord(c);
|
||||
return (v.first - v.second + MODFIXER)%3;
|
||||
return gmod(v.first - v.second, 3);
|
||||
}
|
||||
|
||||
// mapping of the local equilateral triangle
|
||||
@ -578,6 +578,7 @@ EX namespace gp {
|
||||
loctoh_ort(param * loc(0,1)),
|
||||
C03
|
||||
));
|
||||
cgi.gpdata->Tf.resize(S7);
|
||||
for(int i=0; i<S7; i++) {
|
||||
transmatrix T = dir_matrix(i);
|
||||
for(int x=-16; x<16; x++)
|
||||
|
@ -3248,7 +3248,7 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, color_t
|
||||
if(NONSTDVAR || !standard_tiling()) {
|
||||
#if CAP_ARCM
|
||||
if(arcm::in() && !PURE)
|
||||
i = (i + arcm::parent_index_of(c->master)/DUALMUL + MODFIXER) % c->type;
|
||||
i = gmod(i + arcm::parent_index_of(c->master)/DUALMUL, c->type);
|
||||
#endif
|
||||
draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio);
|
||||
return false;
|
||||
|
2
hud.cpp
2
hud.cpp
@ -437,7 +437,7 @@ EX void drawStats() {
|
||||
#if CAP_QUEUE
|
||||
queuecircle(xmove, yb, rad, 0xFF0000FF);
|
||||
queuecircle(xmove, yb, rad*SKIPFAC,
|
||||
legalmoves[MAX_EDGE] ? 0xFF0000FF : 0xFF000080
|
||||
legalmoves[cwt.at->type] ? 0xFF0000FF : 0xFF000080
|
||||
);
|
||||
#endif
|
||||
#if CAP_SHAPES
|
||||
|
@ -110,7 +110,7 @@ struct gcell {
|
||||
#define landparam_color LHU.landpar_color
|
||||
#define fval LHU.fi.fieldval
|
||||
|
||||
#define MAX_EDGE 18
|
||||
#define FULL_EDGE 120
|
||||
|
||||
template<class T> struct walker;
|
||||
|
||||
@ -125,10 +125,12 @@ template<class T> struct walker;
|
||||
* and freed with tailored_free.
|
||||
*/
|
||||
|
||||
int gmod(int i, int j);
|
||||
|
||||
template<class T> struct connection_table {
|
||||
|
||||
/** Table of moves. This is the maximum size, but tailored_alloc allocates less. */
|
||||
T* move_table[MAX_EDGE + (MAX_EDGE + sizeof(char*) - 1) / sizeof(char*)];
|
||||
T* move_table[FULL_EDGE + (FULL_EDGE + sizeof(char*) - 1) / sizeof(char*)];
|
||||
|
||||
unsigned char *spintable() { return (unsigned char*) (&move_table[full()->degree()]); }
|
||||
|
||||
@ -145,7 +147,7 @@ template<class T> struct connection_table {
|
||||
/** on non-orientable surfaces, the d-th edge may be mirrored */
|
||||
bool mirror(int d) { return spintable() [d] & 128; }
|
||||
/** 'fix' the edge number d to get the actual index in [0, degree()) */
|
||||
int fix(int d) { return (d + MODFIXER) % full()->degree(); }
|
||||
int fix(int d) { return gmod(d, full()->degree()); }
|
||||
/** T in the direction i */
|
||||
T*& move(int i) { return move_table[i]; }
|
||||
/** T in the direction i, modulo degree() */
|
||||
|
@ -86,7 +86,7 @@ EX namespace mapeditor {
|
||||
c->hitpoints = c2->hitpoints;
|
||||
if(c2->mondir != NODIR) {
|
||||
auto si2 = patterns::getpatterninfo0(c2);
|
||||
c->mondir = (c2->mondir - si2.dir + si.dir + MODFIXER) % c->type;
|
||||
c->mondir = gmod(c2->mondir - si2.dir + si.dir, c->type);
|
||||
// todo reflect
|
||||
}
|
||||
}
|
||||
@ -434,7 +434,7 @@ namespace mapstream {
|
||||
// printf("%p:%d,%d -> %p\n", c2, relspin[parent], dir, c);
|
||||
|
||||
// spinval becomes xspinval
|
||||
rspin = (c2->c.spin(dir) - f.read_char() + MODFIXER) % (c->type - sub);
|
||||
rspin = gmod(c2->c.spin(dir) - f.read_char(), c->type - sub);
|
||||
if(GDIM == 3 && rspin && !hybri) {
|
||||
println(hlog, "rspin in 3D");
|
||||
throw hstream_exception();
|
||||
@ -898,7 +898,7 @@ namespace mapeditor {
|
||||
c->hitpoints = copywhat->hitpoints;
|
||||
c->stuntime = copywhat->stuntime;
|
||||
if(copywhat->mondir == NODIR) c->mondir = NODIR;
|
||||
else c->mondir = ((where.first.mirrored == where.second.mirrored ? 1 : -1) * (copywhat->mondir - where.second.spin) + cdir + MODFIXER) % c->type;
|
||||
else c->mondir = gmod((where.first.mirrored == where.second.mirrored ? 1 : -1) * (copywhat->mondir - where.second.spin) + cdir, c->type);
|
||||
break;
|
||||
}
|
||||
checkUndo();
|
||||
|
116
monstermove.cpp
116
monstermove.cpp
@ -19,7 +19,7 @@ EX int sagephase = 0;
|
||||
EX vector<cell*> targets;
|
||||
|
||||
/** monsters to move, ordered by the number of possible good moves */
|
||||
vector<cell*> movesofgood[MAX_EDGE+1];
|
||||
grow_vector<vector<cell*>> movesofgood;
|
||||
|
||||
EX vector<pair<cell*, int> > butterflies;
|
||||
|
||||
@ -538,11 +538,12 @@ EX int totalbulldistance(cell *c, int k) {
|
||||
return tbd;
|
||||
}
|
||||
|
||||
EX void determinizeBull(cell *c, int *posdir, int& nc) {
|
||||
EX void determinizeBull(cell *c, vector<int>& posdir) {
|
||||
// determinize the Angry Beast movement:
|
||||
// use the previous PC's positions as the tiebreaker
|
||||
int nc = isize(posdir);
|
||||
for(int k=0; k<SHSIZE && nc>1; k++) {
|
||||
int pts[MAX_EDGE];
|
||||
vector<int> pts(nc);
|
||||
for(int d=0; d<nc; d++) pts[d] = totalbulldistance(c->cmove(posdir[d]), k);
|
||||
|
||||
int bestpts = 1000;
|
||||
@ -551,46 +552,46 @@ EX void determinizeBull(cell *c, int *posdir, int& nc) {
|
||||
for(int d=0; d<nc; d++) if(pts[d] == bestpts) posdir[nc0++] = posdir[d];
|
||||
nc = nc0;
|
||||
}
|
||||
posdir.resize(nc);
|
||||
}
|
||||
|
||||
EX int determinizeBullPush(cellwalker bull) {
|
||||
int nc = 2;
|
||||
int dirs[2], positive;
|
||||
vector<int> dirs(2);
|
||||
int positive;
|
||||
bull += wstep;
|
||||
cell *c2 = bull.at;
|
||||
if(!(c2->type & 1)) return 1; // irrelevant
|
||||
int d = c2->type / 2;
|
||||
bull += d; dirs[0] = positive = bull.spin;
|
||||
bull -= 2*d; dirs[1] = bull.spin;
|
||||
determinizeBull(c2, dirs, nc);
|
||||
determinizeBull(c2, dirs);
|
||||
if(dirs[0] == positive) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int posdir[MAX_EDGE], nc;
|
||||
vector<int> global_posdir;
|
||||
|
||||
EX int pickMoveDirection(cell *c, flagtype mf) {
|
||||
int bestval = stayval(c, mf);
|
||||
nc = 1; posdir[0] = -1;
|
||||
global_posdir = {-1};
|
||||
|
||||
// printf("stayval [%p, %s]: %d\n", c, dnameof(c->monst), bestval);
|
||||
for(int d=0; d<c->type; d++) {
|
||||
cell *c2 = c->move(d);
|
||||
int val = moveval(c, c2, d, mf);
|
||||
// printf("[%d] %p: val=%5d pass=%d\n", d, c2, val, passable(c2,c,0));
|
||||
if(val > bestval) nc = 0, bestval = val;
|
||||
if(val == bestval) posdir[nc++] = d;
|
||||
if(val > bestval) global_posdir.clear(), bestval = val;
|
||||
if(val == bestval) global_posdir.push_back(d);
|
||||
}
|
||||
|
||||
if(c->monst == moRagingBull)
|
||||
determinizeBull(c, posdir, nc);
|
||||
determinizeBull(c, global_posdir);
|
||||
|
||||
if(!nc) return -1;
|
||||
return posdir[hrand(nc)];
|
||||
return hrand_elt(global_posdir, -1);
|
||||
}
|
||||
|
||||
EX int pickDownDirection(cell *c, flagtype mf) {
|
||||
int downs[MAX_EDGE], qdowns = 0;
|
||||
vector<int> downs;
|
||||
int bestdif = -100;
|
||||
forCellIdEx(c2, i, c) {
|
||||
if(gravityLevelDiff(c2, c) < 0 && passable_for(c->monst, c2, c, P_MIRROR) &&
|
||||
@ -602,12 +603,11 @@ EX int pickDownDirection(cell *c, flagtype mf) {
|
||||
// printf("i=%d md=%d dif=%d\n", i, c->mondir, cdif);
|
||||
if(c2->wall == waClosePlate || c->wall == waClosePlate)
|
||||
cdif += 20;
|
||||
if(cdif > bestdif) bestdif = cdif, qdowns = 0;
|
||||
if(cdif == bestdif) downs[qdowns++] = i;
|
||||
if(cdif > bestdif) bestdif = cdif, downs.clear();
|
||||
if(cdif == bestdif) downs.push_back(i);
|
||||
}
|
||||
}
|
||||
if(!qdowns) return -1;
|
||||
return downs[hrand(qdowns)];
|
||||
return hrand_elt(downs, -1);
|
||||
}
|
||||
|
||||
// Angry Beast attack
|
||||
@ -657,7 +657,7 @@ EX cell *moveNormal(cell *c, flagtype mf) {
|
||||
int d;
|
||||
|
||||
if(c->stuntime) {
|
||||
if(cellEdgeUnstable(c, MF_STUNNED)) d = pickDownDirection(c, mf), nc = 1, posdir[0] = d;
|
||||
if(cellEdgeUnstable(c, MF_STUNNED)) d = pickDownDirection(c, mf), global_posdir = {d};
|
||||
else return NULL;
|
||||
}
|
||||
else {
|
||||
@ -706,8 +706,8 @@ EX cell *moveNormal(cell *c, flagtype mf) {
|
||||
}
|
||||
else {
|
||||
bool attacking = false;
|
||||
for(int i=0; i<nc; i++) {
|
||||
cell *c2 = c->move(posdir[i]);
|
||||
for(int dir: global_posdir) {
|
||||
cell *c2 = c->move(dir);
|
||||
|
||||
if(isPlayerOn(c2)) {
|
||||
killThePlayerAt(m, c2, 0);
|
||||
@ -725,8 +725,8 @@ EX cell *moveNormal(cell *c, flagtype mf) {
|
||||
}
|
||||
}
|
||||
|
||||
if(!attacking) for(int i=0; i<nc; i++) {
|
||||
movei mi(c, posdir[i]);
|
||||
if(!attacking) for(int dir: global_posdir) {
|
||||
movei mi(c, dir);
|
||||
if(!c->monst) c->monst = m;
|
||||
moveMonster(mi);
|
||||
if(m == moRagingBull) beastAttack(mi.t, false, false);
|
||||
@ -1152,13 +1152,12 @@ EX void groupmove(eMonster movtype, flagtype mf) {
|
||||
|
||||
for(int i=0; i<isize(gendfs); i++) {
|
||||
cell *c = gendfs[i];
|
||||
int dirtable[MAX_EDGE], qdirtable=0;
|
||||
vector<int> dirtable;
|
||||
|
||||
forCellIdAll(c2,t,c) dirtable[qdirtable++] = t;
|
||||
hrandom_shuffle(dirtable, qdirtable);
|
||||
forCellIdAll(c2,t,c) dirtable.push_back(t);
|
||||
hrandom_shuffle(dirtable);
|
||||
|
||||
while(qdirtable--) {
|
||||
int t = dirtable[qdirtable];
|
||||
for(auto& t: dirtable) {
|
||||
groupmove2(movei(c, t).rev(),movtype,mf);
|
||||
}
|
||||
|
||||
@ -1287,13 +1286,12 @@ EX void movehex(bool mounted, int colorpair) {
|
||||
|
||||
for(int i=0; i<isize(hexdfs); i++) {
|
||||
cell *c = hexdfs[i];
|
||||
int dirtable[MAX_EDGE], qdirtable=0;
|
||||
vector<int> dirtable;
|
||||
for(int t=0; t<c->type; t++) if(c->move(t) && inpair(c->move(t), colorpair))
|
||||
dirtable[qdirtable++] = t;
|
||||
dirtable.push_back(t);
|
||||
|
||||
hrandom_shuffle(dirtable, qdirtable);
|
||||
while(qdirtable--) {
|
||||
int t = dirtable[qdirtable];
|
||||
hrandom_shuffle(dirtable);
|
||||
for(auto& t: dirtable) {
|
||||
hexvisit(c->move(t), c, t, mounted, colorpair);
|
||||
}
|
||||
}
|
||||
@ -1306,13 +1304,11 @@ EX void movehex_rest(bool mounted) {
|
||||
if(c->monst == moHexSnake) {
|
||||
colorpair = snake_pair(c);
|
||||
if(!goodmount(c, mounted)) continue;
|
||||
int t[MAX_EDGE];
|
||||
for(int i=0; i<c->type; i++) t[i] = i;
|
||||
for(int j=1; j<c->type; j++) swap(t[j], t[hrand(j+1)]);
|
||||
vector<int> dirtable = hrandom_permutation(c->type);
|
||||
for(int u=0; u<c->type; u++) {
|
||||
createMov(c, t[u]);
|
||||
if(inpair(c->move(t[u]), colorpair))
|
||||
hexvisit(c, c->move(t[u]), c->c.spin(t[u]), mounted, colorpair);
|
||||
createMov(c, dirtable[u]);
|
||||
if(inpair(c->move(dirtable[u]), colorpair))
|
||||
hexvisit(c, c->move(dirtable[u]), c->c.spin(dirtable[u]), mounted, colorpair);
|
||||
}
|
||||
}
|
||||
if(c->monst == moHexSnake) {
|
||||
@ -1429,7 +1425,7 @@ EX void moveshadow() {
|
||||
EX void moveghosts() {
|
||||
|
||||
if(invismove) return;
|
||||
for(int d=0; d<=MAX_EDGE; d++) movesofgood[d].clear();
|
||||
movesofgood.clear();
|
||||
|
||||
for(int i=0; i<isize(ghosts); i++) {
|
||||
cell *c = ghosts[i];
|
||||
@ -1444,19 +1440,18 @@ EX void moveghosts() {
|
||||
if(ghostmove(c->monst, c->move(k), c) && !isPlayerOn(c->move(k)))
|
||||
goodmoves++;
|
||||
|
||||
movesofgood[goodmoves].push_back(c);
|
||||
movesofgood.grow(goodmoves).push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
for(int d=0; d<=MAX_EDGE; d++) for(int i=0; i<isize(movesofgood[d]); i++) {
|
||||
cell *c = movesofgood[d][i];
|
||||
for(auto& v: movesofgood) for(cell *c: v) {
|
||||
|
||||
if(c->stuntime) continue;
|
||||
if(isPowerMonster(c) && !playerInPower()) continue;
|
||||
|
||||
if(isGhostMover(c->monst) && c->cpdist >= 1) {
|
||||
|
||||
int mdir[MAX_EDGE];
|
||||
vector<int> mdir;
|
||||
|
||||
for(int j=0; j<c->type; j++)
|
||||
if(c->move(j) && canAttack(c, c->monst, c->move(j), c->move(j)->monst, AF_GETPLAYER | AF_ONLY_FBUG)) {
|
||||
@ -1466,12 +1461,11 @@ EX void moveghosts() {
|
||||
goto nextghost;
|
||||
}
|
||||
|
||||
int qmpos = 0;
|
||||
for(int k=0; k<c->type; k++) if(c->move(k) && c->move(k)->cpdist < c->cpdist)
|
||||
if(ghostmove(c->monst, c->move(k), c))
|
||||
mdir[qmpos++] = k;
|
||||
if(!qmpos) continue;
|
||||
int d = mdir[hrand(qmpos)];
|
||||
mdir.push_back(k);
|
||||
if(mdir.empty()) continue;
|
||||
int d = hrand_elt(mdir);
|
||||
cell *c2 = c->move(d);
|
||||
if(c2->monst == moTortoise && c2->stuntime > 1) {
|
||||
addMessage(XLAT("%The1 scares %the2 a bit!", c->monst, c2->monst));
|
||||
@ -1606,15 +1600,16 @@ EX void movegolems(flagtype flags) {
|
||||
for(int i=0; i<ittypes; i++) recorduse[i] = orbused[i];
|
||||
|
||||
DEBB(DF_TURN, ("stayval"));
|
||||
int bestv = stayvalue(m, c), bq = 0, bdirs[MAX_EDGE];
|
||||
int bestv = stayvalue(m, c);
|
||||
vector<int> bdirs;
|
||||
|
||||
DEBB(DF_TURN, ("moveval"));
|
||||
for(int k=0; k<c->type; k++) if(c->move(k)) {
|
||||
cell *c2 = c->move(k);
|
||||
int val = movevalue(m, c, c2, flags);
|
||||
|
||||
if(val > bestv) bestv = val, bq = 0;
|
||||
if(val == bestv) bdirs[bq++] = k;
|
||||
if(val > bestv) bestv = val, bdirs.clear();
|
||||
if(val == bestv) bdirs.push_back(k);
|
||||
}
|
||||
|
||||
if(m == moTameBomberbird) {
|
||||
@ -1622,8 +1617,8 @@ EX void movegolems(flagtype flags) {
|
||||
if(c2 && !c2->monst) {
|
||||
int val = movevalue(m, c, c2, flags);
|
||||
// printf("val = %d bestv = %d\n",
|
||||
if(val > bestv) bestv = val, bq = 0;
|
||||
if(val == bestv) bdirs[bq++] = STRONGWIND;
|
||||
if(val > bestv) bestv = val, bdirs.clear();
|
||||
if(val == bestv) bdirs.push_back(STRONGWIND);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1631,8 +1626,8 @@ EX void movegolems(flagtype flags) {
|
||||
|
||||
// printf("stayvalue = %d, result = %d, bq = %d\n", stayvalue(m,c), bestv, bq);
|
||||
|
||||
if(bq == 0) continue;
|
||||
int dir = bdirs[hrand(bq)];
|
||||
if(bdirs.empty()) continue;
|
||||
int dir = hrand_elt(bdirs);
|
||||
auto mi = movei(c, dir);
|
||||
auto& c2 = mi.t;
|
||||
if(c2->monst) {
|
||||
@ -1882,16 +1877,16 @@ EX void consMove(cell *c, eMonster param) {
|
||||
if(c2 && c2->pathdist < c->pathdist)
|
||||
goodmoves++;
|
||||
}
|
||||
movesofgood[goodmoves].push_back(c);
|
||||
movesofgood.grow(goodmoves).push_back(c);
|
||||
}
|
||||
else
|
||||
movesofgood[0].push_back(c);
|
||||
movesofgood.grow(0).push_back(c);
|
||||
}
|
||||
|
||||
EX void moveNormals(eMonster param) {
|
||||
pathdata pd(param);
|
||||
|
||||
for(int d=0; d<=MAX_EDGE; d++) movesofgood[d].clear();
|
||||
|
||||
movesofgood.clear();
|
||||
|
||||
for(int i=0; i<isize(pathqm); i++)
|
||||
consMove(pathqm[i], param);
|
||||
@ -1902,8 +1897,7 @@ EX void moveNormals(eMonster param) {
|
||||
if(c->pathdist == PINFD) consMove(c, param);
|
||||
}
|
||||
|
||||
for(int d=0; d<=MAX_EDGE; d++) for(int i=0; i<isize(movesofgood[d]); i++) {
|
||||
cell *c = movesofgood[d][i];
|
||||
for(auto& v: movesofgood) for(cell *c: v) {
|
||||
if(minf[c->monst].mgroup == moYeti) {
|
||||
moveNormal(c, MF_PATHDIST);
|
||||
}
|
||||
|
17
netgen.cpp
17
netgen.cpp
@ -57,15 +57,15 @@ EX namespace netgen {
|
||||
vec center[MAXCELLS];
|
||||
double rot[MAXCELLS];
|
||||
int glued[MAXCELLS];
|
||||
int nei[MAXCELLS][MAX_EDGE];
|
||||
vector<int> nei[MAXCELLS];
|
||||
|
||||
// auxiliary data
|
||||
double raylen[MAXCELLS];
|
||||
double edgist[MAXCELLS];
|
||||
char patek[MAXCELLS][MAX_EDGE];
|
||||
vector<char> patek[MAXCELLS];
|
||||
|
||||
// data generated by HyperRogue
|
||||
hyperpoint hcenter[MAXCELLS][MAX_EDGE+1];
|
||||
vector<hyperpoint> hcenter[MAXCELLS];
|
||||
|
||||
// Functions handling the data.
|
||||
//==============================
|
||||
@ -79,7 +79,8 @@ EX namespace netgen {
|
||||
if(mode == 1)
|
||||
for(int ii=0; ii<CELLS; ii++) if(dcal[ii] == c) {
|
||||
|
||||
hcenter[ii][MAX_EDGE] = V * C0;
|
||||
hcenter[ii].resize(c->type+1);
|
||||
hcenter[ii][c->type] = V * C0;
|
||||
|
||||
if(c->type == S7) {
|
||||
for(int i=0; i<c->type; i++) {
|
||||
@ -110,11 +111,12 @@ EX namespace netgen {
|
||||
|
||||
for(int i=0; i<CELLS; i++) {
|
||||
ct[i] = dcal[i]->type;
|
||||
for(int k=0; k<8; k++)
|
||||
for(int k=0; k<=ct[i]; k++)
|
||||
vx[i][2*k] = hcenter[i][k][0],
|
||||
vx[i][2*k+1] = hcenter[i][k][1];
|
||||
|
||||
for(int k=0; k<ct[i]; k++) nei[i][k] = -1;
|
||||
nei[i].clear();
|
||||
nei[i].resize(ct[i], -1);
|
||||
|
||||
for(int j=0; j<CELLS; j++) {
|
||||
cell *c1 = dcal[i];
|
||||
@ -148,6 +150,8 @@ EX namespace netgen {
|
||||
|
||||
for(int i=0; i<CELLS; i++) scan(f, ct[i]);
|
||||
|
||||
for(int i=0; i<CELLS; i++) nei[i].resize(ct[i]);
|
||||
|
||||
for(int i=0; i<CELLS; i++) for(int j=0; j<16; j++) scan(f, vx[i][j]);
|
||||
|
||||
for(int i=0; i<CELLS; i++)
|
||||
@ -343,6 +347,7 @@ EX namespace netgen {
|
||||
SDL_FillRect(net, NULL, 0xFFFFFF);
|
||||
|
||||
int pateks = 0;
|
||||
for(int i=0; i<CELLS; i++) patek[i].resize(ct[i]);
|
||||
|
||||
int zeroi = nei[0][0];
|
||||
int zeroe = 0;
|
||||
|
12
orbs.cpp
12
orbs.cpp
@ -321,8 +321,7 @@ EX bool reflectingBarrierAt(cell *c) {
|
||||
EX bool reflectingBarrierAt(cellwalker& c, int d) {
|
||||
if(d >= 3) return true;
|
||||
if(d <= -3) return true;
|
||||
d = c.spin + d + MODFIXER;
|
||||
d%=c.at->type;
|
||||
d = gmod(c.spin + d, c.at->type);
|
||||
if(!c.at->move(d)) return true;
|
||||
|
||||
return reflectingBarrierAt(c.at->move(d));
|
||||
@ -1104,8 +1103,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
||||
|
||||
// nature
|
||||
if(items[itOrbNature] && numplayers() == 1 && c->monst != moFriendlyIvy) {
|
||||
int dirs[MAX_EDGE];
|
||||
int qsides = 0;
|
||||
vector<int> dirs;
|
||||
forCellIdCM(cf, d, c)
|
||||
if(cf->monst == moFriendlyIvy) {
|
||||
|
||||
@ -1118,11 +1116,11 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
||||
if(strictlyAgainstGravity(c, cf, false, MF_IVY)) continue;
|
||||
if(monstersnear(cwt.at, NULL, moPlayer, c, cwt.at)) continue;
|
||||
}
|
||||
dirs[qsides++] = d;
|
||||
dirs.push_back(d);
|
||||
}
|
||||
|
||||
if(qsides > 0) {
|
||||
int di = dirs[hrand(qsides)];
|
||||
int di = hrand_elt(dirs, -1);
|
||||
if(di != -1) {
|
||||
if(!isCheck(a)) growIvyTo(movei(c, di).rev());
|
||||
return itOrbNature;
|
||||
}
|
||||
|
@ -1278,8 +1278,8 @@ EX int pattern_threecolor(cell *c) {
|
||||
#if CAP_GP
|
||||
if(S3 == 3 && !(S7&1) && gp_threecolor() == 1 && c->master->c7 != c) {
|
||||
auto li = gp::get_local_info(c);
|
||||
int rel = (li.relative.first - li.relative.second + MODFIXER) % 3;
|
||||
int par = (gp::param.first - gp::param.second + MODFIXER) % 3;
|
||||
int rel = gmod(li.relative.first - li.relative.second, 3);
|
||||
int par = gmod(gp::param.first - gp::param.second, 3);
|
||||
if(rel == 0)
|
||||
return pattern_threecolor(c->master->c7);
|
||||
else if(rel == par)
|
||||
@ -1335,7 +1335,7 @@ EX int pattern_threecolor(cell *c) {
|
||||
#if CAP_GP
|
||||
if(gp_threecolor() == 2) {
|
||||
auto li = gp::get_local_info(c);
|
||||
int sp = (MODFIXER + li.relative.first + 2 * li.relative.second) % 3;
|
||||
int sp = gmod(li.relative.first + 2 * li.relative.second, 3);
|
||||
if(sp != 0) {
|
||||
if(li.last_dir & 1)
|
||||
sp = 3 - sp;
|
||||
|
21
quotient.cpp
21
quotient.cpp
@ -12,25 +12,16 @@ namespace hr {
|
||||
|
||||
EX namespace quotientspace {
|
||||
|
||||
bool operator == (const code& c1, const code &c2) {
|
||||
for(int i=0; i<=S7; i++) if(c1.c[i] != c2.c[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator < (const code& c1, const code &c2) {
|
||||
for(int i=0; i<=S7; i++) if(c1.c[i] != c2.c[i]) return c1.c[i] < c2.c[i];
|
||||
return false;
|
||||
}
|
||||
|
||||
int cod(heptagon *h) {
|
||||
return zebra40(h->c7);
|
||||
}
|
||||
|
||||
code get(heptspin hs) {
|
||||
code res;
|
||||
res.c[0] = cod(hs.at);
|
||||
res.connections.resize(S7);
|
||||
res.connections[0] = cod(hs.at);
|
||||
for(int i=1; i<=S7; i++) {
|
||||
res.c[i] = cod((hs + wstep).at);
|
||||
res.connections[i] = cod((hs + wstep).at);
|
||||
hs += 1;
|
||||
}
|
||||
return res;
|
||||
@ -45,7 +36,11 @@ EX namespace quotientspace {
|
||||
|
||||
#if HDR
|
||||
struct code {
|
||||
int c[MAX_EDGE+1];
|
||||
vector<int> connections;
|
||||
|
||||
bool operator == (const code &c2) const { return connections == c2.connections; }
|
||||
bool operator < (const code &c2) const { return connections < c2.connections; }
|
||||
|
||||
};
|
||||
|
||||
struct hrmap_quotient : hrmap_standard {
|
||||
|
2
rug.cpp
2
rug.cpp
@ -609,7 +609,7 @@ EX void buildRug() {
|
||||
rugpoint *v = p.second;
|
||||
|
||||
if(arcm::in() || (euclid && quotient)) {
|
||||
rugpoint *p[MAX_EDGE+1];
|
||||
vector<rugpoint*> p(c->type+1);
|
||||
for(int j=0; j<c->type; j++) p[j] = findOrAddRugpoint(ggmatrix(c) * get_corner_position(c, j), v->dist);
|
||||
for(int j=0; j<c->type; j++) addTriangle(v, p[j], p[(j+1) % c->type]);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user