diff --git a/floorshapes.cpp b/floorshapes.cpp index 177bfcce..4a58a552 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -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 &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 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) { diff --git a/graph.cpp b/graph.cpp index e690baf8..c28094ac 100644 --- a/graph.cpp +++ b/graph.cpp @@ -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; diff --git a/hyper.h b/hyper.h index 62e7f1ef..c4249616 100644 --- a/hyper.h +++ b/hyper.h @@ -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 { diff --git a/mapeditor.cpp b/mapeditor.cpp index 4726e6a4..ccf36c22 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -172,13 +172,13 @@ namespace mapstream { int32_t id = cellids.count(cwt.at) ? cellids[cwt.at] : -1; save(id); - for(int i=0; id[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; id[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; id[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; id[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; imaster) << 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) { diff --git a/polygons.cpp b/polygons.cpp index 7fcb4549..1535793c 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1363,8 +1363,6 @@ hpcshape ld tentacle_length; #define USERLAYERS 32 -#define USERSHAPEGROUPS 4 -#define USERSHAPEIDS 4096 struct usershapelayer { vector list; @@ -1379,7 +1377,7 @@ struct usershape { usershapelayer d[USERLAYERS]; }; -usershape *usershapes[USERSHAPEGROUPS][USERSHAPEIDS]; +array, 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; id[l].sh, us->d[l].sh.prio); diff --git a/textures.cpp b/textures.cpp index b8e784ca..f0bf0f55 100644 --- a/textures.cpp +++ b/textures.cpp @@ -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;