diff --git a/celldrawer.cpp b/celldrawer.cpp index a5ae53a8..1e576507 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -82,6 +82,26 @@ inline void drawcell(cell *c, const shiftmatrix& V) { static constexpr int trapcol[4] = {0x904040, 0xA02020, 0xD00000, 0x303030}; static constexpr int terracol[8] = {0xD000, 0xE25050, 0xD0D0D0, 0x606060, 0x303030, 0x181818, 0x0080, 0x8080}; +EX colortable prairie_colors = { 0x402000, 0x503000 }; +EX colortable mountain_colors = { 0x181008*2, 0x181008*4 }; +EX colortable tower_colors = { 0x202010, 0x404030 }; +EX colortable westwall_colors = { 0x211F6F, 0x413F8F }; +EX colortable endorian_colors = { 0x202010, 0x404030, 0x0000D0 }; +EX colortable canopy_colors = { 0x60C060, 0x489048 }; +EX colortable camelot_cheat_colors = { 0x606060, 0xC0C0C0 }; + +/** return the special colortable for the given cell -- color menu uses this to know that a colortable should be edited */ +EX colortable* special_colortable_for(cell *c) { + if(c->land == laPrairie && prairie::isriver(c)) return &prairie_colors; + if(c->land == laMountain && !c->wall && (eubinary || sphere || c->master->alt)) return &mountain_colors; + if(c->land == laIvoryTower && !c->wall) return &tower_colors; + if(c->land == laWestWall) return &westwall_colors; + if(c->land == laEndorian && !c->wall) return &endorian_colors; + if(c->land == laEndorian && c->wall == waCanopy) return &canopy_colors; + if(c->land == laCamelot && camelotcheat) return &camelot_cheat_colors; + return nullptr; + } + void celldrawer::addaura() { hr::addaura(tC0(V), darkened(aura_color), fd); } @@ -259,7 +279,7 @@ void celldrawer::setcolors() { break; case laMountain: if(eubinary || sphere || c->master->alt) - fcol = 0x181008 * flip_dark(celldistAlt(c), 2, 4); + fcol = get_color_auto3(celldistAlt(c), mountain_colors); else fcol = 0; if(c->wall == waPlatform) wcol = 0xF0F0A0; break; @@ -328,11 +348,11 @@ void celldrawer::setcolors() { break; case laIvoryTower: - fcol = 0x10101 * flip_dark(c->landparam, 32, 64) - 0x000010; + fcol = get_color_auto3(c->landparam, tower_colors); break; case laWestWall: - fcol = 0x10101 * flip_dark(c->landparam, 0, 32) + floorcolors[c->land]; + fcol = get_color_auto3(c->landparam, westwall_colors); break; case laDungeon: { @@ -352,23 +372,21 @@ void celldrawer::setcolors() { case laEndorian: { int clev = pd_from->land == laEndorian ? edgeDepth(pd_from) : 0; // xcol = (c->landparam&1) ? 0xD00000 : 0x00D000; - fcol = 0x10101 * flip_dark(c->landparam, 32, 64) - 0x000010; + fcol = get_color_auto3(c->landparam, endorian_colors, 1); int ed = edgeDepth(c); int sr = get_sightrange_ambush(); if(clev == UNKNOWN || ed == UNKNOWN) - fcol = 0x0000D0; + fcol = endorian_colors.back(); else { while(ed > clev + sr) ed -= 2; while(ed < clev - sr) ed += 2; - fcol = gradient(fcol, 0x0000D0, clev-sr, ed, clev+sr); + fcol = gradient(fcol, endorian_colors.back(), clev-sr, ed, clev+sr); } if(c->wall == waTrunk) fcol = winf[waTrunk].color; if(c->wall == waCanopy || c->wall == waSolidBranch || c->wall == waWeakBranch) { - fcol = winf[waCanopy].color; - int f = flip_dark(c->landparam, 0, 2); - if(f) fcol = gradient(0, fcol, 8, f, 0); + fcol = get_color_auto3(c->landparam, canopy_colors); } break; } @@ -376,7 +394,7 @@ void celldrawer::setcolors() { #if CAP_FIELD case laPrairie: if(prairie::isriver(c)) { - fcol = flip_dark(prairie::get_val(c), 0x402000, 0x503000); + fcol = get_color_auto3(prairie::get_val(c), prairie_colors); } else { fcol = 0x004000 + 0x001000 * c->LHU.fi.walldist; @@ -392,7 +410,7 @@ void celldrawer::setcolors() { #if CAP_TOUR if(!tour::on) camelotcheat = false; if(camelotcheat) - fcol = 0x10101 * flip_dark(d, 0x60, 0xC0); + fcol = get_color_auto3(d, camelot_cheat_colors); else #endif if(d < 0) { diff --git a/config.cpp b/config.cpp index 5cae1ca3..0716150f 100644 --- a/config.cpp +++ b/config.cpp @@ -1382,7 +1382,15 @@ EX void initConfig() { #if CAP_COMPLEX2 param_colortable(brownian::colors, "color:brown"); #endif - + + param_colortable(prairie_colors, "color:prairie"); + param_colortable(mountain_colors, "color:mountain"); + param_colortable(tower_colors, "color:tower"); + param_colortable(westwall_colors, "color:freefall"); + param_colortable(endorian_colors, "color:endorian"); + param_colortable(canopy_colors, "color:canopy"); + param_colortable(camelot_cheat_colors, "color:camelotcheat"); + for(int i=0; imonst].color); else if(c->item) dialog::openColorDialog(iinf[c->item].color); + else if(auto tab = special_colortable_for(c)) { pushScreen([tab] { edit_color_table(*tab); }); return; } else if(c->wall) dialog::openColorDialog(winf[c->wall == waMineMine ? waMineUnknown : c->wall].color); #if CAP_COMPLEX2 diff --git a/graph.cpp b/graph.cpp index 63124e3c..a335294e 100644 --- a/graph.cpp +++ b/graph.cpp @@ -140,15 +140,20 @@ ld spina(cell *c, int dir) { return TAU * dir / c->type; } -/** @brief used to alternate colors depending on distance to something. In chessboard-patterned geometries, also use a third step */ - -EX int flip_dark(int f, int a0, int a1) { - if(geosupport_chessboard()) { +/** @brief used to alternate colors depending on distance to something. In chessboard-patterned geometries, automatically a third step. + * In some cases, we want to avoid a number of colors in the table -- set @param subtract to the number of such colors. + */ +EX color_t get_color_auto3(int f, const colortable& ctab, int subtract IS(0)) { + int size = ctab.size() - subtract; + if(size < 1) return 0; + if(geosupport_chessboard() && size == 2) { f = gmod(f, 3); - return a0 + (a1-a0) * f / 2; + if(f == 1) + return gradient(ctab[0], ctab[1], 0, 1, 2); + return ctab[f/2]; } else - return (f&1) ? a1 : a0; + return ctab[gmod(f, size)]; } color_t fc(int ph, color_t col, int z) {