From 9a731572f63d5cd0bd0643776c18293fc3780bde Mon Sep 17 00:00:00 2001 From: Charlotte Peppers Date: Mon, 31 Jan 2022 14:21:36 -0700 Subject: [PATCH 1/4] Added idle animation option, fixed palace hypersian rugs using "ticks" instead of "pticks" --- config.cpp | 9 +++++++++ graph.cpp | 12 ++++++------ hyper.h | 2 ++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/config.cpp b/config.cpp index 2732fb43..c4bad9df 100644 --- a/config.cpp +++ b/config.cpp @@ -718,6 +718,7 @@ EX void initConfig() { addsaver(fat_edges, "fat-edges"); param_f(vid.sspeed, "sspeed", "scrollingspeed", 0); param_f(vid.mspeed, "mspeed", "movement speed", 1); + param_f(vid.ispeed, "ispeed", "idle speed", 1); addsaver(vid.aurastr, "aura strength", ISMOBILE ? 0 : 128); addsaver(vid.aurasmoothen, "aura smoothen", 5); param_enum(vid.graphglyph, "graphglyph", "graphical items/kills", 1) @@ -1648,6 +1649,14 @@ EX void showGraphConfig() { }); dialog::addSelItem(XLAT("movement animation speed"), fts(vid.mspeed), 'm'); + + dialog::addSelItem(XLAT("idle animation speed"), fts(vid.ispeed), 'i'); + dialog::add_action([] { + dialog::editNumber(vid.ispeed, 0, 4, 0.1, 1, + XLAT("idle animation speed"), + "0 = disable\n\nThis affects non-movement animations such as orb effects, item rotation, and more." + ); + }); dialog::addItem(XLAT("extra graphical effects"), 'u'); diff --git a/graph.cpp b/graph.cpp index 84bac197..9d48710e 100644 --- a/graph.cpp +++ b/graph.cpp @@ -72,7 +72,7 @@ EX int animation_lcm = 0; EX ld ptick(int period, ld phase IS(0)) { if(animation_lcm) animation_lcm = animation_lcm * (period / gcd(animation_lcm, period)); - return (ticks * animation_factor) / period + phase * 2 * M_PI; + return (ticks * animation_factor * vid.ispeed) / period + phase * 2 * M_PI; } EX ld fractick(int period, ld phase IS(0)) { @@ -816,8 +816,8 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int } #if CAP_SHAPES - auto sinptick = [c, pticks] (int period) { return c ? sintick(period) : sin(animation_factor * pticks / period);}; - auto spinptick = [c, pticks] (int period, ld phase) { return c ? spintick(period, phase) : spin((animation_factor * pticks + phase) / period); }; + auto sinptick = [c, pticks] (int period) { return c ? sintick(period) : sin(animation_factor * vid.ispeed * pticks / period);}; + auto spinptick = [c, pticks] (int period, ld phase) { return c ? spintick(period, phase) : spin((animation_factor * vid.ispeed * pticks + phase) / period); }; int ct6 = c ? ctof(c) : 1; hpcshape *xsh = (it == itPirate || it == itKraken) ? &cgi.shPirateX : @@ -934,7 +934,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int if(GDIM == 3 && WDIM == 2) { ld h = cgi.human_height; dynamicval qfi2(qfi, qfi); - shiftmatrix V2 = V * spin(ticks / 1500.); + shiftmatrix V2 = V * spin(pticks * vid.ispeed / 1500.); /* divisors should be higher than in plate renderer */ qfi.fshape = &cgi.shMFloor2; draw_shapevec(c, V2 * zpush(-h/30), qfi.fshape->levels[0], 0xFFD500FF, PPR::WALL); @@ -947,7 +947,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int } else if(WDIM == 3 && c) { ld h = cgi.human_height; - shiftmatrix V2 = Vit * spin(ticks / 1500.); + shiftmatrix V2 = Vit * spin(pticks * vid.ispeed / 1500.); draw_floorshape(c, V2 * zpush(h/100), cgi.shMFloor3, 0xFFD500FF); draw_floorshape(c, V2 * zpush(h/50), cgi.shMFloor4, darkena(icol, 0, 0xFF)); queuepoly(V2, cgi.shGem[ct6], 0xFFD500FF); @@ -959,7 +959,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int #endif { color_t hider = hidden ? 0xFFFFFF20 : 0xFFFFFFFF; - shiftmatrix V2 = Vit * spin(ticks / 1500.); + shiftmatrix V2 = Vit * spin(pticks * vid.ispeed / 1500.); draw_floorshape(c, V2, cgi.shMFloor3, 0xFFD500FF & hider); draw_floorshape(c, V2, cgi.shMFloor4, darkena(icol, 0, 0xFF) & hider); queuepoly(V2, cgi.shGem[ct6], 0xFFD500FF & hider); diff --git a/hyper.h b/hyper.h index 28b0fe55..edc8c652 100644 --- a/hyper.h +++ b/hyper.h @@ -416,6 +416,8 @@ struct videopar { eThreatLevel faraway_highlight; // draw attention to monsters on the horizon int faraway_highlight_color; // 0 = monster color, 100 = red-green oscillation + + ld ispeed; }; extern videopar vid; From ab08a69cc6b8ce605902cb9f5dbe2b6da25f33cb Mon Sep 17 00:00:00 2001 From: Charlotte Peppers Date: Sun, 6 Mar 2022 20:01:59 -0700 Subject: [PATCH 2/4] Added Canvas Floor and Canvas Darkness options --- celldrawer.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ classes.cpp | 12 ++++++++++++ graph.cpp | 5 ++++- mapeditor.cpp | 31 +++++++++++++++++++++++++++++++ mapeffects.cpp | 2 +- 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/celldrawer.cpp b/celldrawer.cpp index fd4b8a01..f88ee13b 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -1057,8 +1057,58 @@ void celldrawer::draw_mirrorwall() { } } +EX int canvasfloor; + void celldrawer::set_land_floor(const shiftmatrix& Vf) { switch(c->land) { + case laCanvas: + switch(canvasfloor) { + case caflM: set_floor(cgi.shMFloor); break; + case caflFull: set_floor(cgi.shFullFloor); break; +// case caflWarp is warped floor + case caflStar: set_floor(cgi.shStarFloor); break; + case caflCloud: set_floor(cgi.shCloudFloor); break; + case caflCross: set_floor(cgi.shCrossFloor); break; + case caflCharged: set_floor(cgi.shChargedFloor); break; + case caflSStar: set_floor(cgi.shSStarFloor); break; + case caflOver: set_floor(cgi.shOverFloor); break; + case caflTri: set_floor(cgi.shTriFloor); break; + case caflFeather: set_floor(cgi.shFeatherFloor); break; + case caflBarrow: set_floor(cgi.shBarrowFloor); break; + case caflNew: set_floor(cgi.shNewFloor); break; + case caflTroll: set_floor(cgi.shTrollFloor); break; + case caflButterfly: set_floor(cgi.shButterflyFloor); break; + case caflLava: set_floor(cgi.shLavaFloor); break; + case caflPalace: set_floor(cgi.shPalaceFloor); break; + case caflDemon: set_floor(cgi.shDemonFloor); break; + case caflCave: set_floor(cgi.shCaveFloor); break; + case caflDesert: set_floor(cgi.shDesertFloor); break; + case caflPower: set_floor(cgi.shPowerFloor); break; + case caflRose: set_floor(cgi.shRoseFloor); break; + case caflTurtle: set_floor(cgi.shTurtleFloor); break; + case caflDragon: set_floor(cgi.shDragonFloor); break; + case caflReptile: set_reptile_floor(V, fcol); break; + case caflHive: + if(c->wall != waFloorB && c->wall != waFloorA && c->wall != waMirror && c->wall != waCloud && !chasmgraph(c)) { + set_floor(cgi.shFloor); + if(GDIM == 2) { + draw_floorshape(c, V, cgi.shMFloor, darkena(fcol, fd + 1, 0xFF), PPR::FLOORa); + draw_floorshape(c, V, cgi.shMFloor2, darkena(fcol, fcol==uint(c->landparam) ? fd : fd + 1, 0xFF), PPR::FLOORb); + } + } + else + set_floor(cgi.shFloor); + break; + case caflSwitch: + set_floor(cgi.shSwitchFloor); + 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 caflNone: default: + set_floor(cgi.shFloor); break; + } + break; + case laPrairie: case laAlchemist: set_floor(cgi.shCloudFloor); diff --git a/classes.cpp b/classes.cpp index 1a765af4..8ac9932b 100644 --- a/classes.cpp +++ b/classes.cpp @@ -626,6 +626,11 @@ EX walltype winf[walltypes] = { // -- land types --- #if HDR +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 }; + static const flagtype LF_GENERATE_ALL = Flag(0); static const flagtype LF_ICY = Flag(1); static const flagtype LF_GRAVITY = Flag(2); @@ -661,6 +666,13 @@ enum eLand { extern color_t floorcolors[landtypes]; #endif +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" + }; + EX const landtype linf[landtypes] = { #define LAND(a,b,c,d,e,f,g) {a,b,d,e,g}, #include "content.cpp" diff --git a/graph.cpp b/graph.cpp index 16ecd733..7ebcfb06 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3674,15 +3674,18 @@ bool allemptynear(cell *c) { } EX bool bright; +EX int canvasdark; // how much to darken EX int getfd(cell *c) { if(bright) return 0; if(among(c->land, laAlchemist, laHell, laVariant, laEclectic) && WDIM == 2 && GDIM == 3) return 0; switch(c->land) { + case laCanvas: + return min(2,max(0,canvasdark)); + case laRedRock: case laReptile: - case laCanvas: return 0; case laSnakeNest: diff --git a/mapeditor.cpp b/mapeditor.cpp index 3c7442ed..37adedef 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -697,6 +697,8 @@ EX namespace mapstream { f.write(canvas_default_wall); f.write(mapeditor::drawplayer); if(patterns::whichCanvas == 'f') f.write(patterns::color_formula); + f.write(canvasfloor); + f.write(canvasdark); { int i = ittypes; f.write(i); @@ -880,6 +882,8 @@ EX namespace mapstream { f.read(canvas_default_wall); f.read(mapeditor::drawplayer); if(patterns::whichCanvas == 'f') f.read(patterns::color_formula); + f.read(canvasfloor); + f.read(canvasdark); int i; f.read(i); if(i > ittypes || i < 0) throw hstream_exception(); @@ -3055,6 +3059,20 @@ EX namespace mapeditor { } #endif + + string canvasFloorName(int id) { + if(id>=0 && idland) || (!inmirrororwall(c->land) && (items[itOrb37] && c->cpdist <= 4)); + return isWarpedType(c->land) || (c->land == laCanvas && canvasfloor == 3) || (!inmirrororwall(c->land) && (items[itOrb37] && c->cpdist <= 4)); } EX bool nonAdjacent(cell *c, cell *c2) { From 904faabd96e470e03856d86b430f2b0a04dab41e Mon Sep 17 00:00:00 2001 From: Charlotte Peppers Date: Mon, 7 Mar 2022 17:37:35 -0700 Subject: [PATCH 3/4] Added tower to canvas floor options, added new Flashing Effects option which currently effects storms and some curses --- celldrawer.cpp | 5 +++-- classes.cpp | 4 ++-- config.cpp | 6 ++++++ graph.cpp | 33 +++++++++++++++++++++++++-------- hyper.h | 1 + 5 files changed, 37 insertions(+), 12 deletions(-) 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; From ff67930be3bc93ec81ec2a45e91c3dc83e45d099 Mon Sep 17 00:00:00 2001 From: Charlotte Peppers Date: Mon, 7 Mar 2022 18:59:49 -0700 Subject: [PATCH 4/4] Added game version check for loading maps with canvas floor and darkening --- mapeditor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mapeditor.cpp b/mapeditor.cpp index 37adedef..bf129019 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -882,8 +882,10 @@ EX namespace mapstream { f.read(canvas_default_wall); f.read(mapeditor::drawplayer); if(patterns::whichCanvas == 'f') f.read(patterns::color_formula); - f.read(canvasfloor); - f.read(canvasdark); + if(f.vernum >= 0xA90C) { // TODO Please replace this with the next version this pull request is included in + f.read(canvasfloor); + f.read(canvasdark); + } int i; f.read(i); if(i > ittypes || i < 0) throw hstream_exception();