mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 01:00:25 +00:00
replaced chosenDown with a better set of functions
This commit is contained in:
parent
08e6990d23
commit
dee2b23991
58
bigstuff.cpp
58
bigstuff.cpp
@ -648,38 +648,6 @@ cell *randomDown(cell *c) {
|
||||
return tab[hrand(q)];
|
||||
}
|
||||
|
||||
// which=1 => right, which=-1 => left
|
||||
|
||||
typedef int cellfunction(cell*);
|
||||
|
||||
int chosenDownId(cell *c, int which, cellfunction* cf) {
|
||||
int d = (*cf)(c)-1;
|
||||
for(int i=0; i<c->type; i++) {
|
||||
if(!c->move(i)) createMov(c, i);
|
||||
if(c->move(i)->mpdist > BARLEV && cf == coastvalEdge) setdist(c->move(i), BARLEV, c);
|
||||
|
||||
if((*cf)(c->move(i)) == d) {
|
||||
again:
|
||||
int i2 = (i+which+MODFIXER)%c->type;
|
||||
createMov(c, i2);
|
||||
if((*cf)(c->move(i2)) == d) {
|
||||
i = i2; goto again;
|
||||
}
|
||||
else return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set which=1,bonus=1 to get right neighbor on level
|
||||
|
||||
cell *chosenDown(cell *c, int which, int bonus, cellfunction* cf) {
|
||||
int id = chosenDownId(c, which, cf);
|
||||
if(id == -1) return NULL;
|
||||
return createMovR(c, id + bonus);
|
||||
}
|
||||
|
||||
int edgeDepth(cell *c) {
|
||||
if(c->land == laIvoryTower || c->land == laEndorian || c->land == laDungeon)
|
||||
return coastvalEdge(c);
|
||||
@ -698,28 +666,12 @@ int getHauntedDepth(cell *c) {
|
||||
return -100;
|
||||
}
|
||||
|
||||
int towerval(cell *c, cellfunction* cf) {
|
||||
// if(c->land != laEdge) return 0;
|
||||
cell *cp1 = chosenDown(c, 1, 1, cf);
|
||||
if(!cp1) return 0;
|
||||
/* cell *cp2 = chosenDown(cp1, 1, 1);
|
||||
if(!cp2) return 0;
|
||||
cell *cm1 = chosenDown(c, -1, -1);
|
||||
if(!cm1) return 0;
|
||||
cell *cm2 = chosenDown(cm1, -1, -1);
|
||||
if(!cm2) return 0; */
|
||||
|
||||
/* return
|
||||
(c->type-6)
|
||||
+ 2*(cp1->type-6) + 4*(cp2->type-6)
|
||||
+ 8*(cm1->type-6) +16*(cm2->type-6); */
|
||||
|
||||
int towerval(cell *c, const cellfunction& cf) {
|
||||
cell *cp1 = ts::left_of(c, cf);
|
||||
if(!cp1) return 0;
|
||||
int under = 0;
|
||||
int cfc = (*cf)(c);
|
||||
for(int i=0; i<c->type; i++) {
|
||||
if(c->move(i) && (*cf)(c->move(i)) < cfc)
|
||||
under++;
|
||||
}
|
||||
int cfc = cf(c);
|
||||
forCellEx(c2, c) if(cf(c2) < cfc) under++;
|
||||
return (c->type-6) + 2*(cp1->type-6) + 4*under;
|
||||
}
|
||||
|
||||
|
44
complex.cpp
44
complex.cpp
@ -3590,8 +3590,10 @@ namespace dungeon {
|
||||
c4 = c2->move(i);
|
||||
}
|
||||
rdepths[i] = c2 && c3 && c4 && (c2->landflags == 3 || c3->landflags == 3 || c4->landflags == 3);
|
||||
c2 = chosenDown(c2, 1, 0); // if(!c2) break;
|
||||
c3 = chosenDown(c3, -1, 0);
|
||||
if(c2) generate_around(c2);
|
||||
if(c3) generate_around(c3);
|
||||
c2 = ts::left_parent(c2, coastvalEdge);
|
||||
c3 = ts::right_parent(c3, coastvalEdge);
|
||||
if(!c2) { towerError(c); return; }
|
||||
if(!c3) { towerError(c); return; }
|
||||
}
|
||||
@ -3604,19 +3606,22 @@ namespace dungeon {
|
||||
else if(!rdepths[2] && !rdepths[4] && !rdepths[1]) {
|
||||
c2 = c;
|
||||
c3 = c;
|
||||
cell *c4 = chosenDown(c, 1, 1);
|
||||
cell *c5 = chosenDown(c, -1, -1);
|
||||
generate_around(c);
|
||||
cell *c4 = ts::left_of(c, coastvalEdge);
|
||||
cell *c5 = ts::right_of(c, coastvalEdge);
|
||||
for(int i=0; i<3; i++) {
|
||||
if(coastvalEdge(c2) == 0) break;
|
||||
if(c2 && c4 && c4->landflags == 3 && c2->landflags != 3 && c4 == chosenDown(c2, 1, 1))
|
||||
for(cell *cx: {c2, c3, c4, c5}) if(cx) generate_around(cx);
|
||||
|
||||
if(c2 && c4 && c4->landflags == 3 && c2->landflags != 3 && c4 == ts::left_of(c2, coastvalEdge))
|
||||
c->wall = waLadder;
|
||||
if(c3 && c5 && c5->landflags == 3 && c3->landflags != 3 && c5 == chosenDown(c3, -1, -1))
|
||||
if(c3 && c5 && c5->landflags == 3 && c3->landflags != 3 && c5 == ts::right_of(c3, coastvalEdge))
|
||||
c->wall = waLadder;
|
||||
buildEquidistant(c4); buildEquidistant(c5);
|
||||
if(c2) c2 = chosenDown(c2, 1, 0);
|
||||
if(c3) c3 = chosenDown(c3, -1, 0);
|
||||
if(c4) c4 = chosenDown(c4, 1, 0);
|
||||
if(c5) c5 = chosenDown(c5, -1, 0);
|
||||
if(c2) c2 = ts::left_parent(c2, coastvalEdge);
|
||||
if(c3) c3 = ts::right_parent(c3, coastvalEdge);
|
||||
if(c4) c4 = ts::left_parent(c4, coastvalEdge);
|
||||
if(c5) c5 = ts::right_parent(c5, coastvalEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3645,8 +3650,10 @@ namespace dungeon {
|
||||
rdepths[i] = c2 && c3 && c4 && (c2->landflags == 3 || c3->landflags == 3 || c4->landflags == 3);
|
||||
if((c2&&c2->landflags == 1) || (c3&&c3->landflags == 1) || (c4&&c4->landflags == 1))
|
||||
switchcount++;
|
||||
c2 = chosenDown(c2, 1, 0); // if(!c2) break;
|
||||
c3 = chosenDown(c3, -1, 0);
|
||||
generate_around(c2);
|
||||
generate_around(c3);
|
||||
c2 = ts::left_parent(c2, coastvalEdge);
|
||||
c3 = ts::right_parent(c3, coastvalEdge);
|
||||
if(!c2) { towerError(c); return 0; }
|
||||
if(!c3) { towerError(c); return 0; }
|
||||
}
|
||||
@ -3696,8 +3703,9 @@ namespace dungeon {
|
||||
int df = dungeonFlags(c);
|
||||
|
||||
if(df&1) {
|
||||
int df1 = dungeonFlags(chosenDown(c,1,1));
|
||||
int df2 = dungeonFlags(chosenDown(c,-1,-1));
|
||||
generate_around(c);
|
||||
int df1 = dungeonFlags(ts::left_of(c, coastvalEdge));
|
||||
int df2 = dungeonFlags(ts::right_of(c, coastvalEdge));
|
||||
|
||||
c->wparam = 0;
|
||||
if(hrand(100) < (c->landparam % 5 == 0 ? 80 : 20)) {
|
||||
@ -3725,10 +3733,10 @@ namespace dungeon {
|
||||
if(q) downs[hrand(q)]->wall = waLadder;
|
||||
*/
|
||||
cell *c2 =
|
||||
c->wparam == 1 ? chosenDown(c, 1, 2) :
|
||||
c->wparam == 2 ? chosenDown(c, -1, -2) :
|
||||
c->wparam == 3 ? chosenDown(c, 1, 3) :
|
||||
c->wparam == 4 ? chosenDown(c, -1, -3) :
|
||||
c->wparam == 1 ? ts::add(c, 1, 2, coastvalEdge) :
|
||||
c->wparam == 2 ? ts::add(c, -1, -2, coastvalEdge) :
|
||||
c->wparam == 3 ? ts::add(c, 1, 3, coastvalEdge) :
|
||||
c->wparam == 4 ? ts::add(c, -1, -3, coastvalEdge) :
|
||||
NULL;
|
||||
|
||||
if(c2) {
|
||||
|
@ -315,7 +315,7 @@ void expansion_analyzer::reset() {
|
||||
descendants.clear();
|
||||
}
|
||||
|
||||
template<class T> int type_in(expansion_analyzer& ea, cell *c, const T& f) {
|
||||
int type_in(expansion_analyzer& ea, cell *c, const cellfunction& f) {
|
||||
if(!ea.N) ea.preliminary_grouping(), ea.reduce_grouping();
|
||||
vector<int> res;
|
||||
res.push_back(subtype(c) * 4 + 2);
|
||||
@ -336,7 +336,7 @@ template<class T> int type_in(expansion_analyzer& ea, cell *c, const T& f) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T> int type_in_quick(expansion_analyzer& ea, cell *c, const T& f) {
|
||||
int type_in_quick(expansion_analyzer& ea, cell *c, const cellfunction& f) {
|
||||
vector<int> res;
|
||||
res.push_back(subtype(c) * 4 + 2);
|
||||
int d = f(c);
|
||||
@ -409,7 +409,7 @@ int curr_dist(cell *c) {
|
||||
|
||||
int position;
|
||||
|
||||
template<class T> int type_in_reduced(expansion_analyzer& ea, cell *c, const T& f) {
|
||||
int type_in_reduced(expansion_analyzer& ea, cell *c, const cellfunction& f) {
|
||||
int a = ea.N;
|
||||
int t = type_in(ea, c, f);
|
||||
if(expansion.N != a) {
|
||||
@ -419,6 +419,69 @@ template<class T> int type_in_reduced(expansion_analyzer& ea, cell *c, const T&
|
||||
return t;
|
||||
}
|
||||
|
||||
// which=1 => right, which=-1 => left
|
||||
|
||||
int parent_id(cell *c, int which, const cellfunction& cf) {
|
||||
int d = cf(c)-1;
|
||||
for(int i=0; i<c->type; i++) {
|
||||
|
||||
if(cf(c->cmove(i)) == d) {
|
||||
again:
|
||||
int i2 = c->c.fix(i+which);
|
||||
if(cf(c->cmove(i2)) == d) {
|
||||
i = i2; goto again;
|
||||
}
|
||||
else return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set which=1,bonus=1 to get right neighbor on level
|
||||
|
||||
void generate_around(cell *c) {
|
||||
forCellCM(c2, c) if(c2->mpdist > BARLEV) setdist(c2, BARLEV, c);
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
cell *verified_add(cell *c, int which, int bonus, const cellfunction& cf) {
|
||||
int id = parent_id(c, which, cf);
|
||||
if(id == -1) return NULL;
|
||||
return c->cmodmove(id + bonus);
|
||||
}
|
||||
|
||||
cell *verified_add_gen(cell *c, int which, int bonus, const cellfunction& cf) {
|
||||
return verified_add(c, which, bonus, cf);
|
||||
}
|
||||
|
||||
cell *add(cell *c, int which, int bonus, const cellfunction& cf) {
|
||||
int pid = parent_id(c, which, cf);
|
||||
if(pid == -1) pid = 0;
|
||||
return c->cmodmove(pid + bonus);
|
||||
}
|
||||
|
||||
cell *left_of(cell *c, const cellfunction& cf) {
|
||||
int pid = parent_id(c, 1, cf);
|
||||
if(pid == -1) return c;
|
||||
if(VALENCE == 3) return c->cmodmove(pid+1);
|
||||
else return (cellwalker(c, pid) + wstep - 1).cpeek();
|
||||
}
|
||||
|
||||
cell *right_of(cell *c, const cellfunction& cf) {
|
||||
int pid = parent_id(c, -1, cf);
|
||||
if(pid == -1) return c;
|
||||
if(VALENCE == 3) return c->cmodmove(pid-1);
|
||||
else return (cellwalker(c, pid) + wstep + 1).cpeek();
|
||||
}
|
||||
|
||||
cell *child_number(cell *c, int id, const cellfunction& cf) {
|
||||
int pid = parent_id(c, 1, cf);
|
||||
if(pid == -1) return c->cmove(id);
|
||||
return c->cmodmove(pid + (VALENCE == 3 ? 2 : 1) + id);
|
||||
}
|
||||
}
|
||||
|
||||
bool viewdists = false, use_color_codes = true, use_analyzer = true, show_distance_lists = true;
|
||||
|
||||
int first_distance = 0, scrolltime = 0;
|
||||
@ -526,7 +589,7 @@ void viewdist_configure_dialog() {
|
||||
bool is_descendant(cell *c) {
|
||||
if(c == cwt.at) return true;
|
||||
if(curr_dist(c) < curr_dist(cwt.at)) return false;
|
||||
return is_descendant(chosenDown(c, -1, 0, curr_dist));
|
||||
return is_descendant(ts::right_parent(c, curr_dist));
|
||||
}
|
||||
|
||||
const int scrollspeed = 100;
|
||||
@ -763,9 +826,7 @@ bool in_segment(cell *left, cell *mid, cell *right) {
|
||||
while(true) {
|
||||
if(mid == left) return true;
|
||||
if(left == right) return false;
|
||||
int v = chosenDownId(left, 1, celldist);
|
||||
if(S3 == 3) left = (cellwalker(left, v) + 1).cpeek();
|
||||
else left = (cellwalker(left, v) + wstep - 1).cpeek();
|
||||
left = ts::right_of(left, celldist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -775,7 +836,7 @@ int sibling_distance(cell *a, cell *b, int limit) {
|
||||
if(a == b) return counting;
|
||||
if(limit == 0) return INF;
|
||||
counting++; limit--;
|
||||
a = chosenDown(a, 1, 1, celldist);
|
||||
a = ts::right_of(a, celldist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -828,18 +889,20 @@ int hyperbolic_celldistance(cell *c1, cell *c2) {
|
||||
}
|
||||
|
||||
if(d >= found_distance) {
|
||||
if(sl_used == sibling_limit) { printf("sibling_limit used: %d\n", sibling_limit); sibling_limit++; }
|
||||
if(sl_used == sibling_limit && IRREGULAR) {
|
||||
printf("sibling_limit used: %d\n", sibling_limit); sibling_limit++;
|
||||
}
|
||||
return found_distance;
|
||||
}
|
||||
|
||||
if(d1 >= d2) {
|
||||
cl1 = chosenDown(cl1, -1, 0, celldist);
|
||||
cr1 = chosenDown(cr1, 1, 0, celldist);
|
||||
cl1 = ts::left_parent(cl1, celldist);
|
||||
cr1 = ts::right_parent(cr1, celldist);
|
||||
d++; d1--;
|
||||
}
|
||||
if(d1 < d2) {
|
||||
cl2 = chosenDown(cl2, -1, 0, celldist);
|
||||
cr2 = chosenDown(cr2, 1, 0, celldist);
|
||||
cl2 = ts::left_parent(cl2, celldist);
|
||||
cr2 = ts::right_parent(cr2, celldist);
|
||||
d++; d2--;
|
||||
}
|
||||
}
|
||||
|
@ -2424,11 +2424,11 @@ transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si) {
|
||||
return V * iddspin(c, 0, M_PI);
|
||||
}
|
||||
|
||||
transmatrix applyDowndir(cell *c, cellfunction *cf) {
|
||||
transmatrix applyDowndir(cell *c, const cellfunction& cf) {
|
||||
return ddspin(c, patterns::downdir(c, cf), M_PI);
|
||||
}
|
||||
|
||||
void set_towerfloor(cell *c, cellfunction *cf = coastvalEdge) {
|
||||
void set_towerfloor(cell *c, const cellfunction& cf = coastvalEdge) {
|
||||
if(weirdhyperbolic || sphere) {
|
||||
set_floor(shFloor);
|
||||
return;
|
||||
@ -2436,7 +2436,7 @@ void set_towerfloor(cell *c, cellfunction *cf = coastvalEdge) {
|
||||
int j = -1;
|
||||
|
||||
if(masterless) j = 10;
|
||||
else if((*cf)(c) > 1) {
|
||||
else if(cf(c) > 1) {
|
||||
int i = towerval(c, cf);
|
||||
if(i == 4) j = 0;
|
||||
if(i == 5) j = 1;
|
||||
@ -4007,7 +4007,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
// queuepoly(Vf, shLeafFloor[ct6], darkena(fcol, fd, 0xFF));
|
||||
|
||||
/* else if(c->land == laPrairie && prairie::isriver(c))
|
||||
set_towerfloor(Vf, c, darkena(fcol, fd, 0xFF),
|
||||
|
||||
set_towerfloor(Vf, c, darkena(fcol, fd, 0xFF),
|
||||
prairie::isleft(c) ? river::towerleft : river::towerright); */
|
||||
|
||||
else switch(c->land) {
|
||||
|
30
hyper.h
30
hyper.h
@ -518,6 +518,7 @@ struct heptagon {
|
||||
heptagon () { heptacount++; }
|
||||
~heptagon () { heptacount--; }
|
||||
heptagon *cmove(int d) { return createStep(this, d); }
|
||||
heptagon *cmodmove(int d) { return createStep(this, c.fix(d)); }
|
||||
inline int degree();
|
||||
|
||||
// prevent accidental copying
|
||||
@ -541,6 +542,7 @@ struct cell : gcell {
|
||||
cell*& move(int d) { return c.move(d); }
|
||||
cell*& modmove(int d) { return c.modmove(d); }
|
||||
cell* cmove(int d) { return createMov(this, d); }
|
||||
cell* cmodmove(int d) { return createMov(this, c.fix(d)); }
|
||||
cell() {}
|
||||
|
||||
// prevent accidental copying
|
||||
@ -643,8 +645,6 @@ int numplayers();
|
||||
void removeIvy(cell *c);
|
||||
bool cellEdgeUnstable(cell *c, flagtype flags = 0);
|
||||
int coastvalEdge(cell *c);
|
||||
typedef int cellfunction(cell*);
|
||||
int towerval(cell *c, cellfunction* cf = &coastvalEdge);
|
||||
#define HRANDMAX 0x7FFFFFFF
|
||||
int hrandpos(); // 0 to HRANDMAX
|
||||
|
||||
@ -1064,6 +1064,8 @@ extern string mouseovers;
|
||||
|
||||
extern struct SDL_Surface *s;
|
||||
|
||||
typedef function<int(cell*)> cellfunction;
|
||||
|
||||
namespace patterns {
|
||||
extern char whichShape;
|
||||
extern int canvasback;
|
||||
@ -1128,7 +1130,7 @@ namespace patterns {
|
||||
void showPattern();
|
||||
void val38(cell *c, patterninfo &si, int sub, int pat);
|
||||
|
||||
int downdir(cell *c, cellfunction *cf = coastvalEdge);
|
||||
int downdir(cell *c, const cellfunction& cf = coastvalEdge);
|
||||
}
|
||||
|
||||
namespace mapeditor {
|
||||
@ -1372,7 +1374,6 @@ extern bool buggyGeneration;
|
||||
int buildIvy(cell *c, int children, int minleaf);
|
||||
int celldistAltRelative(cell *c);
|
||||
int roundTableRadius(cell *c);
|
||||
cell *chosenDown(cell *c, int which, int bonus, cellfunction* cf = &coastvalEdge);
|
||||
eLand pickLandRPM(eLand old);
|
||||
bool bearsCamelot(eLand l);
|
||||
|
||||
@ -4203,7 +4204,26 @@ struct expansion_analyzer {
|
||||
|
||||
extern expansion_analyzer expansion;
|
||||
|
||||
int chosenDownId(cell *c, int which, cellfunction* cf);
|
||||
int towerval(cell *c, const cellfunction& cf);
|
||||
|
||||
int parent_id(cell *c, int which, const cellfunction& cf);
|
||||
|
||||
extern int sibling_limit;
|
||||
extern void set_sibling_limit();
|
||||
int type_in_reduced(expansion_analyzer& ea, cell *c, const function<int(cell*)>& f);
|
||||
|
||||
namespace ts {
|
||||
cell *verified_add(cell *c, int which, int bonus, const cellfunction& cf);
|
||||
cell *add(cell *c, int which, int bonus, const cellfunction& cf);
|
||||
|
||||
inline cell *left_parent(cell *c, const cellfunction& cf) { return verified_add(c, 1, 0, cf); }
|
||||
inline cell *right_parent(cell *c, const cellfunction& cf) { return verified_add(c, -1, 0, cf); }
|
||||
cell *left_of(cell *c, const cellfunction& cf);
|
||||
cell *right_of(cell *c, const cellfunction& cf);
|
||||
cell *child_number(cell *c, int id, const cellfunction& cf);
|
||||
}
|
||||
|
||||
void generate_around(cell *c);
|
||||
|
||||
}
|
||||
|
||||
|
14
pattern2.cpp
14
pattern2.cpp
@ -543,10 +543,8 @@ namespace patterns {
|
||||
}
|
||||
}
|
||||
|
||||
int downdir(cell *c, cellfunction *cf) {
|
||||
cell *c2 = chosenDown(c, 1, 1, cf);
|
||||
if(!c2) return 0;
|
||||
return neighborId(c, c2);
|
||||
int downdir(cell *c, const cellfunction& cf) {
|
||||
return parent_id(c, 1, cf) + 1;
|
||||
}
|
||||
|
||||
void applySym0123(int& i, int sub) {
|
||||
@ -1025,8 +1023,8 @@ namespace patterns {
|
||||
}
|
||||
|
||||
else if(pat == PAT_DOWN) {
|
||||
si.id = towerval(c);
|
||||
si.dir = downdir(c);
|
||||
si.id = towerval(c, coastvalEdge);
|
||||
si.dir = downdir(c, coastvalEdge);
|
||||
}
|
||||
|
||||
else if(pat == PAT_FIELD) {
|
||||
@ -2082,14 +2080,14 @@ namespace linepatterns {
|
||||
break;
|
||||
|
||||
case patTriTree: {
|
||||
cell *parent = chosenDown(c, -1, 0, curr_dist);
|
||||
cell *parent = ts::right_parent(c, curr_dist);
|
||||
if(gmatrix.count(parent))
|
||||
queuelinef(tC0(V), gmatrix[parent]*C0, col, 2 + vid.linequality);
|
||||
break;
|
||||
}
|
||||
|
||||
case patTriOther: {
|
||||
cell *parent = chosenDown(c, -1, 0, curr_dist);
|
||||
cell *parent = ts::right_parent(c, curr_dist);
|
||||
forCellEx(c2, c) if(gmatrix.count(c2) && curr_dist(c2) < curr_dist(c) && c2 != parent)
|
||||
queuelinef(tC0(V), gmatrix[c2]*C0, col, 2 + vid.linequality);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user