1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-06-23 13:43:19 +00:00

customizable colors for game objects

This commit is contained in:
Zeno Rogue 2018-11-08 21:56:06 +01:00
parent 01d6a78ceb
commit c3c465f742
8 changed files with 240 additions and 75 deletions

View File

@ -239,6 +239,7 @@ extern monstertype minf[motypes];
extern itemtype iinf[ittypes];
extern const landtype linf[landtypes];
extern color_t floorcolors[landtypes];
enum cpatterntype {
cpFootball, cpThree, cpChess, cpSingle, cpSingleSym, cpOddEven, cpLarge, cpZebra, cpUnknown

View File

@ -17,6 +17,8 @@ videopar vid;
#define ANDROID_SETTINGS ;
#endif
extern color_t floorcolors[landtypes];
charstyle& getcs(int id) {
if(multi::players>1 && id >= 0 && id < multi::players)
return multi::scs[id];
@ -114,6 +116,11 @@ void loadcs(FILE *f, charstyle& cs, int xvernum) {
}
#endif
void savecolortable(colortable& ct, string name) {
for(int i=0; i<isize(ct); i++)
addsaver(ct[i], "color:" + name + ":" + its(i));
}
void initConfig() {
// basic config
@ -235,7 +242,23 @@ void initConfig() {
addsaver(backcolor, "color:background");
addsaver(forecolor, "color:foreground");
addsaver(bordcolor, "color:borders");
addsaver(ringcolor, "color:ring");
addsaver(modelcolor, "color:model");
addsaver(periodcolor, "color:period");
addsaver(dialog::dialogcolor, "color:dialog");
for(auto& p: colortables)
savecolortable(p.second, s0+"canvas"+p.first);
savecolortable(distcolors, "distance");
savecolortable(minecolors, "mines");
for(int i=0; i<motypes; i++)
addsaver(minf[i].color, "color:monster:" + its(i));
for(int i=0; i<ittypes; i++)
addsaver(iinf[i].color, "color:item:" + its(i));
for(int i=0; i<landtypes; i++)
addsaver(floorcolors[i], "color:land:" + its(i));
for(int i=0; i<walltypes; i++)
addsaver(winf[i].color, "color:wall:" + its(i));
// modes
@ -727,11 +750,10 @@ void showGraphConfig() {
menuitem_sightrange();
dialog::addSelItem(XLAT("compass size"), its(vid.mobilecompasssize), 'c');
dialog::addSelItem(XLAT("aura brightness"), its(vid.aurastr), 'z');
dialog::addSelItem(XLAT("aura smoothening factor"), its(vid.aurasmoothen), 'x');
dialog::addSelItem(XLAT("compass size"), its(vid.mobilecompasssize), 'C');
dialog::addItem(XLAT("customize colors and aura"), 'c');
showAllConfig();
dialog::display();
@ -742,10 +764,12 @@ void showGraphConfig() {
char xuni = uni | 96;
if((uni >= 32 && uni < 64) || uni == 'L') xuni = uni;
if((uni >= 32 && uni < 64) || uni == 'L' || uni == 'C') xuni = uni;
if(xuni == 'u') vid.particles = !vid.particles;
if(xuni == 'd') vid.graphglyph = (1+vid.graphglyph)%3;
if(xuni == 'c') pushScreen(show_color_dialog);
if(xuni == 'j') {
dialog::editNumber(whatever, -10, 10, 1, 0, XLAT("whatever"),
@ -805,7 +829,7 @@ void showGraphConfig() {
dialog::reaction = [] () { resetGeometry(); };
}
if(xuni == 'c') {
if(xuni == 'C') {
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), "");
// we need to check the moves
dialog::reaction = checkmove;
@ -826,11 +850,6 @@ void showGraphConfig() {
if(xuni =='p')
vid.backeffects = !vid.backeffects;
if(xuni =='z')
dialog::editNumber(vid.aurastr, 0, 256, 10, 128, XLAT("aura brightness"), "");
else if(xuni =='x')
dialog::editNumber(vid.aurasmoothen, 1, 180, 1, 5, XLAT("aura smoothening factor"), "");
handleAllConfig(sym, xuni);
};
}
@ -1391,6 +1410,117 @@ void showCustomizeChar() {
};
}
void refresh_canvas() {
manual_celllister cl;
cl.add(cwt.at);
int at = 0;
while(at < isize(cl.lst)) {
cell *c2 = cl.lst[at];
c2->landparam = patterns::generateCanvas(c2);
at++;
forCellEx(c3, c2) cl.add(c3);
}
}
void edit_color_table(colortable& ct, const reaction_t& r = reaction_t()) {
cmode = sm::SIDE;
gamescreen(0);
dialog::init(XLAT("Customize colors and aura"));
for(int i=0; i<isize(ct); i++) {
dialog::addColorItem(its(i), ct[i] << 8, 'a'+i);
dialog::add_action([i, &ct, r] () { dialog::openColorDialog(ct[i]); dialog::reaction = r; dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; });
}
dialog::addBack();
dialog::display();
}
void show_color_dialog() {
cmode = sm::SIDE | sm::DIALOG_STRICT_X;
gamescreen(0);
dialog::init(XLAT("Customize colors and aura"));
dialog::addColorItem(XLAT("background"), backcolor << 8, 'b');
dialog::add_action([] () { dialog::openColorDialog(backcolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("foreground"), forecolor << 8, 'f');
dialog::add_action([] () { dialog::openColorDialog(forecolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("borders"), bordcolor << 8, 'o');
dialog::add_action([] () { dialog::openColorDialog(bordcolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("projection boundary"), ringcolor, 'r');
dialog::add_action([] () { dialog::openColorDialog(ringcolor); dialog::dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("projection content"), modelcolor, 'c');
dialog::add_action([] () { dialog::openColorDialog(modelcolor); dialog::dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("projection period"), periodcolor, 'p');
dialog::add_action([] () { dialog::openColorDialog(periodcolor); dialog::dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("dialogs"), dialog::dialogcolor << 8, 'd');
dialog::add_action([] () { dialog::openColorDialog(dialog::dialogcolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; });
dialog::addBreak(50);
if(specialland == laCanvas && colortables.count(patterns::whichCanvas)) {
dialog::addItem(XLAT("pattern colors"), 'P');
dialog::add_action([] () { pushScreen([] () { edit_color_table(colortables[patterns::whichCanvas], refresh_canvas); });});
}
if(cwt.at->land == laMinefield) {
dialog::addItem(XLAT("minefield colors"), 'm');
dialog::add_action([] () { pushScreen([] () { edit_color_table(minecolors); });});
}
if(viewdists) {
dialog::addItem(XLAT("distance colors"), 'd');
dialog::add_action([] () { pushScreen([] () { edit_color_table(distcolors); });});
}
dialog::addInfo(XLAT("colors of some game objects can be edited by clicking them."));
dialog::addBreak(50);
dialog::addSelItem(XLAT("aura brightness"), its(vid.aurastr), 'a');
dialog::add_action([] () { dialog::editNumber(vid.aurastr, 0, 256, 10, 128, XLAT("aura brightness"), ""); });
dialog::addSelItem(XLAT("aura smoothening factor"), its(vid.aurasmoothen), 's');
dialog::add_action([] () { dialog::editNumber(vid.aurasmoothen, 1, 180, 1, 5, XLAT("aura smoothening factor"), ""); });
dialog::addBreak(50);
dialog::addBack();
dialog::display();
getcstat = '-';
keyhandler = [] (int sym, int uni) {
if(uni == '-') {
cell *c = mouseover;
if(!c) return;
else if(c == cwt.at) {
pushScreen(showCustomizeChar);
return;
}
else if(c->monst)
dialog::openColorDialog(minf[c->monst].color);
else if(c->item)
dialog::openColorDialog(iinf[c->item].color);
else if(c->wall)
dialog::openColorDialog(winf[c->wall].color);
else
dialog::openColorDialog(floorcolors[c->land]);
dialog::colorAlpha = false;
dialog::dialogflags |= sm::SIDE;
return;
}
else dialog::handleNavigation(sym, uni);
if(doexiton(sym, uni)) popScreen();
};
}
#if CAP_CONFIG
void resetConfigMenu() {
dialog::init(XLAT("reset all configuration"));

View File

@ -346,17 +346,6 @@ void handleKeyNormal(int sym, int uni) {
if(uni == sym && DEFAULTNOR(sym)) {
gmodekeys(sym, uni);
if(sym == '8') {
backcolor = backcolor ^ 0xFFFFFF;
bordcolor = bordcolor ^ 0xFFFFFF;
forecolor = forecolor ^ 0xFFFFFF;
printf("back = %x\n", backcolor);
}
if(sym == '9') {
pmodel = eModel(8 - pmodel);
// vid.yshift = 1 - vid.yshift;
// vid.drawmousecircle = true;
}
if(sym == 'm' && canmove && (centerover == cwt ? mouseover : centerover.at))
performMarkCommand(mouseover);
}

View File

@ -472,27 +472,27 @@ namespace dialog {
bool handleKeyColor(int sym, int uni) {
unsigned& color = *colorPointer;
int shift = colorAlpha ? 0 : 8;
if(uni >= 'A' && uni <= 'D') {
int x = (mousex - (dcenter-dwidth/4)) * 510 / dwidth;
if(x < 0) x = 0;
if(x > 255) x = 255;
unsigned char* pts = (unsigned char*) &color;
pts[uni - 'A'] = x;
part(color, uni - 'A') = x;
}
else if(uni == ' ' || uni == '\n' || uni == '\r') {
bool inHistory = false;
for(int i=0; i<10; i++) if(colorhistory[i] == (unsigned) color)
for(int i=0; i<10; i++) if(colorhistory[i] == (color << shift))
inHistory = true;
if(!inHistory) { colorhistory[lch] = color; lch++; lch %= 10; }
if(!inHistory) { colorhistory[lch] = (color << shift); lch++; lch %= 10; }
if(reaction) reaction();
popScreen();
}
else if(uni >= '0' && uni <= '9') {
color = colorhistory[uni - '0'];
color = colorhistory[uni - '0'] >> shift;
}
else if(palette && uni >= 'a' && uni < 'a'+(int) palette[0]) {
color = palette[1 + uni - 'a'];
color = palette[1 + uni - 'a'] >> shift;
}
else if(sym == SDLK_DOWN || sym == SDLK_KP2) {
colorp = (colorp-1) & 3;
@ -514,6 +514,8 @@ namespace dialog {
return false;
}
bool colorAlpha;
void drawColorDialog() {
cmode = sm::NUMBER | dialogflags;
if(cmode & sm::SIDE) gamescreen(0);
@ -555,19 +557,20 @@ namespace dialog {
for(int i=0; i<4; i++) {
int y = vid.yres / 2 + (2-i) * vid.fsize * 2;
if(i == 3 && !colorAlpha) continue;
color_t col = ((i==colorp) && !mousing) ? 0xFFD500 : dialogcolor;
displayColorButton(dcenter - dwidth/4, y, "(", 0, 16, 0, col);
string rgt = ") "; rgt += "ABGR" [i];
string rgt = ") "; rgt += "ABGR" [i+(colorAlpha?0:1)];
displayColorButton(dcenter + dwidth/4, y, rgt, 0, 0, 0, col);
displayColorButton(dcenter - dwidth/4 + dwidth * ((color >> (8*i)) & 0xFF) / 510, y, "#", 0, 8, 0, col);
displayColorButton(dcenter - dwidth/4 + dwidth * part(color, i) / 510, y, "#", 0, 8, 0, col);
if(mousey >= y - vid.fsize && mousey < y + vid.fsize)
getcstat = 'A' + i, inslider = true;
}
displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + itsh(color), ' ', 8, 0, color >> ash);
displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + itsh(color), ' ', 8, 0, color >> (colorAlpha ? ash : 0));
if(extra_options) extra_options();
@ -576,6 +579,7 @@ namespace dialog {
void openColorDialog(unsigned int& col, unsigned int *pal) {
colorPointer = &col; palette = pal;
colorAlpha = true;
dialogflags = 0;
pushScreen(drawColorDialog);
reaction = reaction_t();

121
graph.cpp
View File

@ -2691,6 +2691,53 @@ ld wavefun(ld x) {
colortable nestcolors = { 0x800000, 0x008000, 0x000080, 0x404040, 0x700070, 0x007070, 0x707000, 0x606060 };
color_t floorcolors[landtypes];
void init_floorcolors() {
for(int i=0; i<landtypes; i++)
floorcolors[i] = linf[i].color;
floorcolors[laDesert] = 0xEDC9AF;
floorcolors[laKraken] = 0x20A020;
floorcolors[laDocks] = 0x202020;
floorcolors[laCA] = 0x404040;
floorcolors[laMotion] = 0xF0F000;
floorcolors[laGraveyard] = 0x107010;
floorcolors[laWineyard] = 0x006000;
floorcolors[laLivefjord] = 0x306030;
floorcolors[laMinefield] = 0x80A080;
floorcolors[laCaribbean] = 0x006000;
floorcolors[laAlchemist] = 0x202020;
floorcolors[laRlyeh] = 0x004080;
floorcolors[laHell] = 0xC00000;
floorcolors[laCrossroads] = 0xFF0000;
floorcolors[laJungle] = 0x008000;
floorcolors[laZebra] = 0xE0E0E0;
floorcolors[laCaves] = 0x202020;
floorcolors[laEmerald] = 0x202020;
floorcolors[laDeadCaves] = 0x202020;
floorcolors[laPalace] = 0x806020;
floorcolors[laHunting] = 0x40E0D0 / 2;
floorcolors[laBlizzard] = 0x5050C0;
floorcolors[laCocytus] = 0x80C0FF;
floorcolors[laIce] = 0x8080FF;
floorcolors[laCamelot] = 0xA0A0A0;
floorcolors[laOvergrown] = 0x00C020;
floorcolors[laClearing] = 0x60E080;
floorcolors[laHaunted] = 0x609F60;
floorcolors[laMirror] = floorcolors[laMirrorWall] = floorcolors[laMirrorOld] = 0x808080;
}
void setcolors(cell *c, color_t& wcol, color_t& fcol) {
wcol = fcol = winf[c->wall].color;
@ -2735,29 +2782,33 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
case laCrossroads2: case laCrossroads3: case laCrossroads4: case laCrossroads5:
case laRose: case laPower: case laWildWest: case laHalloween: case laRedRock:
case laDragon: case laStorms: case laTerracotta: case laMercuryRiver:
fcol = linf[c->land].color; break;
case laDesert: case laKraken: case laDocks: case laCA:
case laMotion: case laGraveyard: case laWineyard: case laLivefjord:
case laRlyeh: case laHell: case laCrossroads: case laJungle:
case laAlchemist:
fcol = floorcolors[c->land]; break;
case laRuins:
fcol = pseudohept(c) ? 0xC0E0C0 : 0x40A040;
break;
case laDual:
fcol = linf[c->land].color;
fcol = floorcolors[c->land];
if(c->landparam == 2) fcol = 0x40FF00;
if(c->landparam == 3) fcol = 0xC0FF00;
break;
case laDesert: fcol = 0xEDC9AF; break;
case laKraken: fcol = 0x20A020; break;
case laDocks: fcol = 0x202020; break;
case laCA: fcol = 0x404040; break;
case laMotion: fcol = 0xF0F000; break;
case laGraveyard: fcol = 0x107010; break;
case laWineyard: fcol = 0x006000; break;
case laLivefjord: fcol = 0x306030; break;
case laBrownian:
fcol = wcol = gradient(0x002000, 0xFFFFFF, 0, c->landparam, 20);
#if CAP_COMPLEX2
case laBrownian: {
using brownian::level;
fcol = wcol =
c->landparam == 0 ? 0x0000F0 :
c->landparam < level ? gradient(0x002000, 0xFFFFFF, 1, c->landparam, level-1) :
c->landparam < 2 * level ? 0xFFFF80 :
// gradient(0xFFFF80, 0xFFFF00, 2*level, c->landparam, 2*level-1) :
c->landparam < 3 * level ? 0xFF8000 :
// gradient(0xFF8000, 0xFFF000, 2*level, c->landparam, 3*level-1) :
0xC00000;
break;
case laVolcano: {
@ -2781,25 +2832,20 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
}
case laMinefield:
fcol = 0x80A080;
fcol = floorcolors[c->land];
if(c->wall == waMineMine && ((cmode & sm::MAP) || !canmove))
fcol = wcol = 0xFF4040;
break;
case laCaribbean:
if(c->wall != waCIsland && c->wall != waCIsland2)
fcol = 0x006000;
fcol = floorcolors[c->land];
break;
case laAlchemist:
fcol = 0x202020;
break;
case laReptile:
fcol = reptilecolor(c);
break;
case laCrossroads:
fcol = (stereo::in_anaglyph() ? 0xFF3030 : 0xFF0000);
break;
case laCaves: case laEmerald: case laDeadCaves:
fcol = 0x202020;
if(c->land == laEmerald)
@ -2808,11 +2854,9 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
if(c->wall == waCavewall) wcol = 0xC0FFC0;
}
break;
case laJungle:
fcol = (stereo::in_anaglyph() ? 0x408040 : 0x008000);
break;
case laMirror: case laMirrorWall: case laMirrorOld:
fcol = 0x808080;
if(c->land == laMirrorWall) fcol = floorcolors[laMirror];
else fcol = floorcolors[c->land];
break;
case laDryForest:
fcol = gradient(0x008000, 0x800000, 0, c->landparam, 10);
@ -2823,17 +2867,11 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
else fcol = 0;
if(c->wall == waPlatform) wcol = 0xF0F0A0;
break;
case laRlyeh:
fcol = (stereo::in_anaglyph() ? 0x4080C0 : 0x004080);
break;
case laHell:
fcol = (stereo::in_anaglyph() ? 0xC03030 : 0xC00000);
break;
case laCanvas:
fcol = c->landparam;
break;
case laPalace:
fcol = 0x806020;
fcol = floorcolors[c->land];
if(c->wall == waClosedGate || c->wall == waOpenGate)
fcol = wcol;
break;
@ -2841,7 +2879,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
fcol = (linf[c->barleft].color>>1) + (linf[c->barright].color>>1);
break;
case laZebra:
fcol = 0xE0E0E0;
fcol = floorcolors[c->land];
if(c->wall == waTrapdoor) fcol = 0x808080;
break;
case laHive:
@ -2861,7 +2899,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
else if(c->wall == waSmallTree) wcol = 0x905000;
break;
case laOvergrown: case laClearing:
fcol = (c->land == laOvergrown/* || (celldistAlt(c)&1)*/) ? 0x00C020 : 0x60E080;
fcol = floorcolors[c->land];
if(c->wall == waSmallTree) wcol = 0x008060;
else if(c->wall == waBigTree) wcol = 0x0080C0;
break;
@ -2888,9 +2926,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
break;
case laHunting:
// fcol = pseudohept(c) ? 0x205050 : 0x306060;
fcol = 0x40E0D0;
fcol /= 2;
fcol = floorcolors[c->land];
if(pseudohept(c)) fcol = fcol * 3/4;
break;
@ -2955,7 +2991,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
else
#endif
if(d < 0) {
fcol = 0xA0A0A0;
fcol = floorcolors[c->land];
}
else {
// a nice floor pattern
@ -2975,11 +3011,12 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
case laIce: case laCocytus: case laBlizzard:
if(isIcyWall(c)) {
float h = HEAT(c);
bool showcoc = c->land == laCocytus && chaosmode && !wmescher;
eLand l = c->land;
if(l == laCocytus && (!chaosmode || !wmescher)) l = laIce;
color_t colorN04 = showcoc ? 0x4080FF : 0x4040FF;
color_t colorN04 = l == laCocytus ? 0x4080FF : 0x4040FF;
color_t colorN10 = 0x0000FF;
color_t color0 = c->land == laBlizzard ? 0x5050C0 : showcoc ? 0x80C0FF : 0x8080FF;
color_t color0 = floorcolors[c->land];
color_t color02 = 0xFFFFFF;
color_t color06 = 0xFF0000;
color_t color08 = 0xFFFF00;
@ -3035,7 +3072,7 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->item)
itcolor = 1;
if(c->item) itcolor |= 2;
fcol = 0x609F60 + 0x202020 * itcolor;
fcol = floorcolors[laHaunted] + 0x202020 * itcolor;
forCellEx(c2, c) if(c2->monst == moFriendlyGhost)
fcol = gradient(fcol, fghostcolor(c2), 0, .25, 1);

View File

@ -17,8 +17,8 @@ vector<string> extra_keys = {
"5 = change wall display mode",
"6 = change grid",
"7 = change heptagon marking",
"8 = change background color",
"9 = hyperboloid model",
// "8 = change background color",
// "9 = hyperboloid model",
"qweasdzxc, hjklyubn, numpad = move/skip turn",
"arrows = panning",
"o = world overview",

View File

@ -1763,6 +1763,7 @@ namespace dialog {
void addBigItem(string body, int key);
void addColorItem(string body, int value, int key);
void openColorDialog(color_t& col, color_t *pal = palette);
extern bool colorAlpha;
void addHelp(string body);
void addInfo(string body, color_t color = dialogcolor);
void addItem(string body, int key);
@ -4329,5 +4330,7 @@ bool haveaura();
string parser_help();
static const ld degree = M_PI / 180;
void show_color_dialog();
}

View File

@ -23,6 +23,7 @@ int startseed = 0;
eLand firstland0;
void initAll() {
init_floorcolors();
showstartmenu = true;
ca::init();
#if CAP_COMMANDLINE