1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-06-20 12:20:01 +00:00

Fixed mapediting floorshapes. Also works nicely for all geometries now. Enum used for shapegroups.

This commit is contained in:
Zeno Rogue 2018-08-27 19:27:35 +02:00
parent e54da982d1
commit ff84f63abd
7 changed files with 114 additions and 85 deletions

View File

@ -572,19 +572,21 @@ namespace gp {
}
qfloorinfo qfi;
qfloorinfo qfi_dc;
int chasmg;
void set_no_floor() {
qfi.fshape = NULL;
qfi.shape = NULL;
qfi.tinf = NULL;
qfi.usershape = -1;
}
void set_floor(floorshape& sh) {
qfi.fshape = &sh;
qfi.shape = NULL;
qfi.tinf = NULL;
qfi.usershape = -1;
}
void set_floor(hpcshape& sh) {
@ -592,12 +594,14 @@ void set_floor(hpcshape& sh) {
qfi.fshape = NULL;
qfi.spin = Id;
qfi.tinf = NULL;
qfi.usershape = -1;
}
void set_floor(const transmatrix& spin, hpcshape& sh) {
qfi.shape = &sh;
qfi.fshape = NULL;
qfi.spin = spin;
qfi.usershape = -1;
}
void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, int col, int prio = -1) {
@ -639,6 +643,9 @@ void draw_floorshape(cell *c, const transmatrix& V, const floorshape &fsh, int c
void draw_qfi(cell *c, const transmatrix& V, int col, int prio = -1, vector<hpcshape> floorshape::* tab = &floorshape::b) {
if(qfi.shape)
queuepolyat(V * qfi.spin, *qfi.shape, col, prio);
else if(qfi.usershape >= 0) {
mapeditor::drawUserShape(V * qfi.spin, mapeditor::sgFloor, qfi.usershape, col, c);
}
else if(!qfi.fshape) ;
#if CAP_TEXTURE
else if(qfi.tinf) {

View File

@ -603,6 +603,9 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
}
if(c && conformal::includeHistory && conformal::infindhistory.count(c)) poly_outline = OUTLINE_DEAD;
if(c == mapeditor::drawcell && mapeditor::drawcellShapeGroup() == mapeditor::sgItem)
mapeditor::drawtrans = V;
if(!mmitem && it) return true;
@ -659,7 +662,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
xsh = NULL;
}
else if(mapeditor::drawUserShape(V, 2, it, darkena(icol, 0, 0xFF), c)) ;
else if(mapeditor::drawUserShape(V, mapeditor::sgItem, it, darkena(icol, 0, 0xFF), c)) ;
else if(it == itRose) {
for(int u=0; u<4; u++)
@ -766,6 +769,9 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
else if (m == moTortoise || m == moPlayer || (where && !where->stuntime)) ;
else if(where && !(isMetalBeast(m) && where->stuntime == 1))
drawStunStars(V, where->stuntime);
if(where == mapeditor::drawcell && mapeditor::drawcellShapeGroup() == (m == moPlayer ? mapeditor::sgPlayer : mapeditor::sgMonster))
mapeditor::drawtrans = V;
if(m == moTortoise) {
int bits = where ? tortoise::getb(where) : tortoise::last;
@ -777,10 +783,8 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
else if(m == moPlayer) {
charstyle& cs = getcs();
bool havus = mapeditor::drawUserShape(V, 0, cs.charid, cs.skincolor, where);
if(mapeditor::drawplayer && !havus) {
if(mapeditor::drawplayer && !mapeditor::drawUserShape(V, mapeditor::sgPlayer, cs.charid, cs.skincolor, where)) {
if(cs.charid >= 8) {
if(!mmspatial && !footphase)
@ -906,12 +910,14 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
}
}
else if(mapeditor::drawUserShape(V, 1, m, darkena(col, 0, 0xFF), where)) return false;
else if(mapeditor::drawUserShape(V, mapeditor::sgMonster, m, darkena(col, 0, 0xFF), where)) {
return false;
}
else if(isMimic(m) || m == moShadow || m == moIllusion) {
charstyle& cs = getcs();
if(mapeditor::drawUserShape(V, 0, (cs.charid&1)?1:0, darkena(col, 0, 0x80), where)) return false;
if(mapeditor::drawUserShape(V, mapeditor::sgPlayer, cs.charid, darkena(col, 0, 0x80), where)) return false;
if(cs.charid >= 8) {
queuepoly(VABODY, shWolfBody, darkena(col, 0, 0xC0));
@ -1869,8 +1875,14 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
Vb = Vb * ddspin(c, c->mondir);
length = cellgfxdist(c, c->mondir);
}
if(c == mapeditor::drawcell && mapeditor::drawcellShapeGroup() == 1)
mapeditor::drawtrans = Vb;
if(mapeditor::drawUserShape(Vb, 1, c->monst, (col << 8) + 0xFF, c)) return false;
if(mapeditor::drawUserShape(Vb, mapeditor::sgMonster, c->monst, (col << 8) + 0xFF, c)) {
if(c == mapeditor::drawcell) mapeditor::drawtrans = Vb;
return false;
}
if(isIvy(c) || isMutantIvy(c) || c->monst == moFriendlyIvy)
queuepoly(Vb, shIBranch, (col << 8) + 0xFF);
@ -3117,6 +3129,8 @@ void floorShadow(cell *c, const transmatrix& V, int col) {
if(qfi.shape) {
queuepolyat(V * qfi.spin * shadowmulmatrix, *qfi.shape, col, PPR_WALLSHADOW);
}
else if(qfi.usershape >= 0)
mapeditor::drawUserShape(V * qfi.spin * shadowmulmatrix, mapeditor::sgFloor, qfi.usershape, col, c, PPR_WALLSHADOW);
else
draw_shapevec(c, V, qfi.fshape->shadow, col, PPR_WALLSHADOW);
}
@ -3173,7 +3187,7 @@ void escherSidewall(cell *c, int sidepar, const transmatrix& V, int col) {
bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, int col) {
if(!qfi.fshape || !qfi.fshape->is_plain || !validsidepar[sidepar]) {
if(!qfi.fshape || !qfi.fshape->is_plain || !validsidepar[sidepar] || qfi.usershape >= 0) {
escherSidewall(c, sidepar, V, col);
return true;
}
@ -3742,7 +3756,12 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
chasmg = chasmgraph(c);
int fd = getfd(c);
int flooralpha = 255;
if((cmode & sm::DRAW) && mapeditor::drawcell && mapeditor::drawcellShapeGroup() == 3)
flooralpha = 0xC0;
if(c->wall == waMagma) fd = 0;
poly_outline = OUTLINE_DEFAULT;
@ -3766,6 +3785,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
poly_outline = OUTLINE_DEFAULT;
if(!wmascii) {
int gc;
// floor
@ -3775,6 +3795,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
bool eoh = euclid || nonbitrunc;
if(c == mapeditor::drawcell)
mapeditor::drawtrans = V * applyPatterndir(c, si);
if(c->wall == waChasm) {
zcol = 0;
int rd = rosedist(c);
@ -3790,8 +3813,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
#if CAP_EDIT
else if(mapeditor::drawUserShape(V * applyPatterndir(c, si), 3, si.id,
darkena(fcol, fd, (cmode & sm::DRAW) ? 0xC0 : 0xFF), c));
else if(mapeditor::haveUserShape(mapeditor::sgFloor, gc = si.id + patterns::subcode(c, si))) {
qfi.usershape = gc;
qfi.spin = applyPatterndir(c, si);
}
else if(patterns::whichShape == '7')
set_floor(shBigHepta);
@ -4183,7 +4208,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
draw_qfi(c, (*Vdp), darkena(fcol, fd0, 0x80), PPR_LAKELEV);
}
else {
draw_qfi(c, V, darkena(fcol, fd, 0xFF));
draw_qfi(c, V, darkena(fcol, fd, flooralpha));
}
// walls
@ -4612,15 +4637,6 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
}
#if CAP_EDIT
if(c == mapeditor::drawcell) {
if(mapeditor::drawcellShapeGroup() == 2) {
mapeditor::drawtrans = V;
}
qfi_dc = qfi;
}
#endif
if(it) {
if((c->land == laWhirlwind || c->item == itBabyTortoise) && c->wall != waBoat) {
double footphase = 0;

View File

@ -1095,6 +1095,13 @@ namespace mapeditor {
void initdraw(cell *c);
void showMapEditor();
void showDrawEditor();
enum eShapegroup { sgPlayer, sgMonster, sgItem, sgFloor };
static const int USERSHAPEGROUPS = 4;
bool drawUserShape(transmatrix V, eShapegroup group, int id, int color, cell *c, int priority = -1);
bool haveUserShape(eShapegroup group, int id);
}
struct renderbuffer;
@ -3538,10 +3545,10 @@ struct qfloorinfo {
const hpcshape *shape;
const floorshape *fshape;
textureinfo *tinf;
int usershape;
};
extern qfloorinfo qfi;
extern qfloorinfo qfi_dc;
extern int chasmg;
struct hpcshape {

View File

@ -172,13 +172,13 @@ namespace mapstream {
int32_t id = cellids.count(cwt.at) ? cellids[cwt.at] : -1;
save(id);
for(int i=0; i<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) {
usershape *us = usershapes[i][j];
for(int i=0; i<mapeditor::USERSHAPEGROUPS; i++) for(auto usp: usershapes[i]) {
usershape *us = usp.second;
if(!us) continue;
for(int l=0; l<USERLAYERS; l++) if(isize(us->d[l].list)) {
usershapelayer& ds(us->d[l]);
save(i); save(j); save(l); save(ds.sym); save(ds.rots); save(ds.color);
save(i); save(usp.first); save(l); save(ds.sym); save(ds.rots); save(ds.color);
n = isize(ds.list); save(n);
savePoint(ds.shift);
savePoint(ds.spin);
@ -335,8 +335,7 @@ namespace mapstream {
int i = loadInt();
if(i == -1) break;
int j = loadInt(), l = loadInt();
if(i<0 || i >= USERSHAPEGROUPS) break;
if(j<0 || j >= USERSHAPEIDS) break;
if(i<0 || i >= mapeditor::USERSHAPEGROUPS) break;
if(l<0 || l >= USERLAYERS) break;
initShape(i, j);
@ -532,18 +531,19 @@ namespace mapeditor {
return 1;
}
int drawcellShapeGroup() {
if(drawcell == cwt.at && drawplayer) return 0;
if(drawcell->monst) return 1;
if(drawcell->item) return 2;
return 3;
eShapegroup drawcellShapeGroup() {
if(drawcell == cwt.at && drawplayer) return sgPlayer;
if(drawcell->monst) return sgMonster;
if(drawcell->item) return sgItem;
return sgFloor;
}
int drawcellShapeID() {
if(drawcell == cwt.at && drawplayer) return vid.cs.charid;
if(drawcell->monst) return drawcell->monst;
if(drawcell->item) return drawcell->item;
return patterns::getpatterninfo0(drawcell).id;
auto si = patterns::getpatterninfo0(drawcell);
return si.id + patterns::subcode(drawcell, si);
}
bool editingShape(int group, int id) {
@ -995,31 +995,27 @@ namespace mapeditor {
sg = drawcellShapeGroup();
switch(sg) {
case 0:
case sgPlayer:
line1 = XLAT("character");
line2 = csname(vid.cs);
break;
case 1:
case sgMonster:
line1 = XLAT("monster");
line2 = XLAT1(minf[drawcell->monst].name);
break;
case 2:
case sgItem:
line1 = XLAT("item");
line2 = XLAT1(iinf[drawcell->item].name);
break;
case 3:
case sgFloor:
line1 = XLAT("floor");
line2 = XLAT(ishept(drawcell) ? "heptagonal" :
ishex1(drawcell) ? "hexagonal #1" : "hexagonal");
break;
default:
line1 = XLAT("floor/pattern");
line2 = "#" + its(patterns::getpatterninfo0(drawcell).id);
break;
line2 = "#" + its(drawcellShapeID());
/* line2 = XLAT(ishept(drawcell) ? "heptagonal" :
ishex1(drawcell) ? "hexagonal #1" : "hexagonal"); */
break;
}
us =usershapes[drawcellShapeGroup()][drawcellShapeID()];
@ -1031,7 +1027,7 @@ namespace mapeditor {
displayfr(8, 8+fs, 2, vid.fsize, line1, 0xC0C0C0, 0);
if(!intexture) {
if(sg >= 3)
if(sg == sgFloor)
displayButton(8, 8+fs*2, line2 + XLAT(" (r = complex tesselations)"), 'r', 0);
else
displayfr(8, 8+fs*2, 2, vid.fsize, line2, 0xC0C0C0, 0);
@ -1387,14 +1383,14 @@ namespace mapeditor {
fprintf(f, "%x\n", VERNUM_HEX);
if(VERNUM_HEX >= 0xA0A0)
fprintf(f, "%d %d %d %d\n", geometry, nonbitrunc, patterns::whichPattern, patterns::subpattern_flags);
for(int i=0; i<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) {
usershape *us = usershapes[i][j];
for(int i=0; i<USERSHAPEGROUPS; i++) for(auto usp: usershapes[i]) {
usershape *us = usp.second;
if(!us) continue;
for(int l=0; l<USERLAYERS; l++) if(isize(us->d[l].list)) {
usershapelayer& ds(us->d[l]);
fprintf(f, "\n%d %d %d %d %d %6x %d\n",
i, j, l, ds.sym, ds.rots, ds.color, int(isize(ds.list)));
i, usp.first, l, ds.sym, ds.rots, ds.color, int(isize(ds.list)));
writeHyperpoint(f, ds.shift);
writeHyperpoint(f, ds.spin);
fprintf(f,"\n");
@ -1552,10 +1548,7 @@ namespace mapeditor {
else {
dslayer %= USERLAYERS;
int sg = drawcellShapeGroup();
for(int i=0; i<USERSHAPEIDS; i++) if(editingShape(sg, i))
applyToShape(sg, i, uni, mh);
applyToShape(drawcellShapeGroup(), drawcellShapeID(), uni, mh);
if(uni == 'e' || (uni == '-' && mousekey == 'e')) {
initdraw(mouseover ? mouseover : cwt.at);
@ -1568,13 +1561,13 @@ namespace mapeditor {
if(uni == 'b') autochoose = !autochoose;
if(uni == 'S') {
for(int i=0; i<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) {
usershape *us = usershapes[i][j];
for(int i=0; i<USERSHAPEGROUPS; i++) for(auto usp: usershapes[i]) {
auto us = usp.second;
if(!us) continue;
for(int l=0; l<USERLAYERS; l++) if(isize(us->d[l].list)) {
usershapelayer& ds(us->d[l]);
printf("// %d %d %d [%06X]\n", i, j, l, ds.color);
printf("// %d %d %d [%06X]\n", i, usp.first, l, ds.color);
printf(" ID, %d, %d, ", us->d[l].rots, us->d[l].sym?2:1);
for(int i=0; i<isize(us->d[l].list); i++)
printf("%lf,%lf, ", double(us->d[l].list[i][0]), double(us->d[l].list[i][1]));
@ -1603,10 +1596,12 @@ namespace mapeditor {
});
if(sym == SDLK_F5) {
for(int i=0; i<USERSHAPEGROUPS; i++)
for(int j=0; j<USERSHAPEIDS; j++)
if(usershapes[i][j]) delete usershapes[i][j];
}
for(int i=0; i<USERSHAPEGROUPS; i++) {
for(auto us: usershapes[i])
if(us.second) delete us.second;
usershapes[i].clear();
}
}
}
if(rebuildPolys)
@ -1656,12 +1651,18 @@ namespace mapeditor {
}
#endif
bool drawUserShape(transmatrix V, int group, int id, int color, cell *c) {
bool haveUserShape(eShapegroup group, int id) {
#if !CAP_EDIT
return false;
#else
return usershapes[group].count(id) && usershapes[group][id];
#endif
}
bool drawUserShape(transmatrix V, eShapegroup group, int id, int color, cell *c, int priority) {
#if !CAP_EDIT
return false;
#else
id = id % USERSHAPEIDS;
usershape *us = usershapes[group][id];
if(us) {
@ -1671,7 +1672,7 @@ namespace mapeditor {
hpcshape& sh(ds.sh);
if(sh.s != sh.e)
queuepoly(V, sh, ds.color ? ds.color : color);
queuepolyat(V, sh, ds.color ? ds.color : color, priority);
}
}

View File

@ -1882,6 +1882,16 @@ namespace patterns {
pushScreen(showChangeablePatterns);
computeCgroup();
}
int subcode(cell *c, const patterninfo& si) {
if(irr::on)
return irr::cellindex[c] << 8;
else if(archimedean)
return arcm::id_of(c->master) << 8;
else if(!gp::on) return 0;
else if(c == c->master->c7) return (fixdir(si.dir, c) << 8);
else return (get_code(gp::get_local_info(c)) << 16) | (fixdir(si.dir, c) << 8);
}
}
bool is_master(cell *c) {

View File

@ -1363,8 +1363,6 @@ hpcshape
ld tentacle_length;
#define USERLAYERS 32
#define USERSHAPEGROUPS 4
#define USERSHAPEIDS 4096
struct usershapelayer {
vector<hyperpoint> list;
@ -1379,7 +1377,7 @@ struct usershape {
usershapelayer d[USERLAYERS];
};
usershape *usershapes[USERSHAPEGROUPS][USERSHAPEIDS];
array<map<int, usershape*>, mapeditor::USERSHAPEGROUPS> usershapes;
transmatrix ddi(int a, ld x) { return xspinpush(a * M_PI / S42, x); }
@ -2433,8 +2431,8 @@ void buildpolys() {
prehpc = isize(hpc);
DEBB(DF_INIT, (debugfile,"hpc = %d\n", prehpc));
for(int i=0; i<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) {
usershape *us = usershapes[i][j];
for(int i=0; i<mapeditor::USERSHAPEGROUPS; i++) for(auto usp: usershapes[i]) {
auto us = usp.second;
if(!us) continue;
for(int l=0; l<USERLAYERS; l++) {
bshape(us->d[l].sh, us->d[l].sh.prio);

View File

@ -284,16 +284,6 @@ int getTriangleID(cell *c, patterns::patterninfo& si, hyperpoint h) {
return best;
}
int goldbergcode(cell *c, const patterns::patterninfo& si) {
if(irr::on)
return irr::cellindex[c] << 8;
else if(archimedean)
return arcm::id_of(c->master) << 8;
else if(!gp::on) return 0;
else if(c == c->master->c7) return (fixdir(si.dir, c) << 8);
else return (get_code(gp::get_local_info(c)) << 16) | (fixdir(si.dir, c) << 8);
}
void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const transmatrix& T, int shift = 0) {
mi.c = c;
mi.symmetries = si.symmetries;
@ -347,7 +337,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) {
return false;
}
try {
auto& mi = texture_map.at(si.id + goldbergcode(c, si));
auto& mi = texture_map.at(si.id + patterns::subcode(c, si));
set_floor(shFullFloor);
qfi.tinf = &mi;
@ -382,7 +372,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) {
return true;
}
catch(out_of_range&) {
// printf("Ignoring tile #%d / %08x: not mapped\n", si.id, goldbergcode(c, si));
// printf("Ignoring tile #%d / %08x: not mapped\n", si.id, patterns::subcode(c, si));
return false;
}
}
@ -425,7 +415,7 @@ void texture_config::perform_mapping() {
// int sgn = sphere ? -1 : 1;
si.id += goldbergcode(c, si);
si.id += patterns::subcode(c, si);
if(!texture_map.count(si.id))
replace = true;
@ -1458,7 +1448,7 @@ void texture_config::true_remap() {
auto si = patterns::getpatterninfo0(c);
int oldid = si.id;
si.id += goldbergcode(c, si);
si.id += patterns::subcode(c, si);
if(texture_map.count(si.id)) continue;