diff --git a/celldrawer.cpp b/celldrawer.cpp index f88ee13b..80e94ceb 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -1104,6 +1104,7 @@ void celldrawer::set_land_floor(const shiftmatrix& Vf) { if(!chasmgraph(c) && ctof(c) && STDVAR && !arcm::in() && !bt::in() && GDIM == 2) for(int i=0; itype; i++) queuepoly(Vf * ddspin(c, i, M_PI/S7) * xpush(cgi.rhexf), cgi.shSwitchDisk, darkena(fcol, fd, 0xFF)); break; + case caflTower: set_towerfloor(celldist); break; case caflNone: default: set_floor(cgi.shFloor); break; } @@ -2516,7 +2517,7 @@ void celldrawer::add_map_effects() { for(int t=0; ttype; t++) if(c->move(t)) { if(c->move(t)->ligon) { int lcol = darkena(gradient(iinf[itOrbLightning].color, 0, 0, tim, 1100), 0, 0xFF); - queueline(V*chei(xspinpush(ticks * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(currentmap->adj(c, t), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality); + queueline(V*chei(xspinpush((vid.flasheffects ? ticks : ptick(8)) * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(currentmap->adj(c, t), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality); } for(int u: {-1, 1}) { cellwalker cw = cellwalker(c, t) + wstep + u; @@ -2524,7 +2525,7 @@ void celldrawer::add_map_effects() { cell *c2 = cw.peek(); if(c2 && c2->ligon) { int lcol = darkena(gradient(iinf[itOrbLightning].color, 0, 0, tim, 1100), 0, 0xFF); - queueline(V*chei(xspinpush(ticks * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(currentmap->adj(c, t)*currentmap->adj(cw.at, cw.spin), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality); + queueline(V*chei(xspinpush((vid.flasheffects ? ticks : ptick(8)) * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(currentmap->adj(c, t)*currentmap->adj(cw.at, cw.spin), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality); } } } diff --git a/classes.cpp b/classes.cpp index 8ac9932b..0459cfbf 100644 --- a/classes.cpp +++ b/classes.cpp @@ -629,7 +629,7 @@ EX walltype winf[walltypes] = { enum eCanvasFloor { caflNone, caflM, caflFull, caflWarp, caflStar, caflCloud, caflCross, caflCharged, caflSStar, caflOver, caflTri, caflFeather, caflBarrow, caflNew, caflTroll, caflButterfly, caflLava, caflPalace, caflDemon, caflCave, caflDesert, caflPower, caflRose, caflTurtle, caflDragon, caflReptile, - caflHive, caflSwitch, caflEND }; + caflHive, caflSwitch, caflTower, caflEND }; static const flagtype LF_GENERATE_ALL = Flag(0); static const flagtype LF_ICY = Flag(1); @@ -670,7 +670,7 @@ EX const char *canvasFloorNames[caflEND] = { "default", "smaller", "full", "warped", "star", "cloud", "cross", "charged", "saloon", "overgrown", "triangle", "feather", "barrow", "elemental", "troll", "butterfly", "lava", "palace", "demon", "cave", "desert", "power", "rose", "turtle", "dragon", "reptile", - "hive", "jelly" + "hive", "jelly", "tower" }; EX const landtype linf[landtypes] = { diff --git a/config.cpp b/config.cpp index 90560c30..8155cb78 100644 --- a/config.cpp +++ b/config.cpp @@ -725,6 +725,8 @@ EX void initConfig() { param_enum(vid.graphglyph, "graphglyph", "graphical items/kills", 1) -> editable({{"letters", ""}, {"auto", ""}, {"images", ""}}, "inventory/kill mode", 'd'); + addsaver(vid.flasheffects, "flasheffects", 1); + param_f(vid.binary_width, "bwidth", "binary-tiling-width", 1); param_custom(vid.binary_width, "binary tiling width", menuitem_binary_width, 'v'); @@ -1659,6 +1661,10 @@ EX void showGraphConfig() { ); }); + dialog::addBoolItem_action(XLAT("flashing effects"), (vid.flasheffects), 'h'); + if(getcstat == 'h') + mouseovers = XLAT("Disable if you are photosensitive. Replaces flashing effects such as Orb of Storms lightning with slow, adjustable animations."); + dialog::addItem(XLAT("extra graphical effects"), 'u'); dialog::addBreak(50); diff --git a/graph.cpp b/graph.cpp index 7ebcfb06..6f96e274 100644 --- a/graph.cpp +++ b/graph.cpp @@ -299,22 +299,39 @@ void drawWinter(const shiftmatrix& V, ld hdir, color_t col) { void drawLightning(const shiftmatrix& V) { #if CAP_QUEUE + float ds = ptick(600); color_t col = darkena(iinf[itOrbLightning].color, 0, 0xFF); for(int u=0; u<20; u++) { - ld leng = 0.5 / (0.1 + (rand() % 100) / 100.0); - ld rad = rand() % 1000; + ld leng, rad; + if(vid.flasheffects) { + leng = 0.5 / (0.1 + (rand() % 100) / 100.0); + rad = rand() % 1000; + } + else { + if(u % 5) leng = 1.25 + sintick(200, ld(u) * 1.25) * 0.25; + else leng = 2 + sintick(200, ld(u) * 1.25); + rad = (u + ds) * (M_PI / 10); + } shiftmatrix V1 = chei(V, u, 20); queueline(V1*xspinpush0(rad, cgi.hexf*0.3), V1*xspinpush0(rad, cgi.hexf*leng), col, 2 + vid.linequality); } #endif } -void drawCurse(const shiftmatrix& V, color_t col) { +void drawCurse(const shiftmatrix& V, eItem it) { #if CAP_QUEUE - col = darkena(col, 0, 0xFF); + float ds = ptick(450) + (it * 5.5); // Extra offset so both Gluttony and Repulsion are easily visible + color_t col = darkena(iinf[it].color, 0, 0xFF); for(int u=0; u<20; u++) { - ld leng = 0.6 + 0.3 * randd(); - ld rad = rand() % 1000; + ld leng, rad; + if(vid.flasheffects) { + leng = 0.6 + 0.3 * randd(); + rad = rand() % 1000; + } + else { + leng = 0.85 + sintick(150, ld(u) * 1.25) * 0.15; + rad = (u + ds) * (M_PI / 10); + } shiftmatrix V1 = chei(V, u, 20); queueline(V1*xspinpush0(rad, cgi.hexf*0.3), V1*xspinpush0(rad, cgi.hexf*leng), col, 2 + vid.linequality); } @@ -330,8 +347,8 @@ EX void drawPlayerEffects(const shiftmatrix& V, cell *c, eMonster m) { if(items[itOrbShell] > (shmup::on ? 0 : ORBBASE)) drawShield(V, itOrbShell); if(items[itOrbSpeed]) drawSpeed(V); - if(items[itCurseGluttony]) drawCurse(V, iinf[itCurseGluttony].color); - if(items[itCurseRepulsion]) drawCurse(V, iinf[itCurseRepulsion].color); + if(items[itCurseGluttony]) drawCurse(V, itCurseGluttony); + if(items[itCurseRepulsion]) drawCurse(V, itCurseRepulsion); if(onplayer && (items[itOrbSword] || items[itOrbSword2])) { using namespace sword; diff --git a/hyper.h b/hyper.h index beaf7b6c..c303b878 100644 --- a/hyper.h +++ b/hyper.h @@ -418,6 +418,7 @@ struct videopar { int faraway_highlight_color; // 0 = monster color, 100 = red-green oscillation ld ispeed; + bool flasheffects; }; extern videopar vid;