diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index 0671ef9f..9faca218 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -279,6 +279,8 @@ struct entity { struct bbox get_pixel_bbox_at(xy, ld scalex = 1, ld scaley = 1); struct bbox get_pixel_bbox() { return get_pixel_bbox_at(where); } + struct xy get_precise_bbox_at(xy, int mx, int my, ld scalex = 1, ld scaley = 1); + virtual double grav() { return 0.1; } bool on_floor, fallthru, on_ice, wallhug, on_bounce, is_stable; diff --git a/rogueviz/ru/entity.cpp b/rogueviz/ru/entity.cpp index 284ce7ab..b47b1178 100644 --- a/rogueviz/ru/entity.cpp +++ b/rogueviz/ru/entity.cpp @@ -17,6 +17,15 @@ bbox entity::get_pixel_bbox_at(xy p, ld scalex, ld scaley) { return b; } +xy entity::get_precise_bbox_at(xy p, int mx, int my, ld scalex, ld scaley) { + double d = get_scale_at(p.y); + ld dx = d * scalex; + ld dy = d * scaley; + double man_x = siz().x; + double man_y = siz().y; + return xy { p.x + mx * man_x * dx / 2, p.y + my * man_y * dy / 2 }; + } + void entity::on_fountain() { hs(fountain_resetter); } bool entity::visible(room *r) { @@ -253,6 +262,40 @@ void entity::apply_walls() { if(reset) goto again; } } + + for(int x = jbb.minx; x < jbb.maxx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) { + eWall b = current_room->at(x, y); + if(walls[b].flags & W_SLOPE) { + + bool left = walls[b].glyph[0] == '\\'; + + auto bad = [&] (xy p) { + if(left) + return -p.x + p.y >= -block_x * x + block_y * y && p.y >= block_y * y && p.x <= block_x * (x + 1); + else + return p.x + p.y >= block_x * x + block_y * y + block_x && p.y >= block_y * y && p.x >= block_x * x; + }; + auto p = get_precise_bbox_at(where + vel, left ? -1 : 1, 1); + + if(loopcount > 200) { + println(hlog, "[slope loop error]"); + continue; + } + + if(bad(p)) { + ld target_vy; + target_vy = left ? vel.x : -vel.x; + if(target_vy > 0) target_vy *= .9; + if(vel.y > target_vy - 1e-6) vel.y = target_vy; + else if(vel.y > target_vy + 1e-6) vel.y = (vel.y + target_vy) / 2; + on_floor = true; + if(walls[b].flags & W_STABLE) is_stable = true; + goto again; + } + } + } + + // println(hlog, format("%.20lf %.20lf %.20lf %.20lf L%d -> %.20lf %.20lf", where.x, where.y, vel.x, vel.y, loopcount, (where+vel).x, (where+vel).y)); } bool entity::stay_on_screen() { diff --git a/rogueviz/ru/globals.cpp b/rogueviz/ru/globals.cpp index bce1371a..f683e110 100644 --- a/rogueviz/ru/globals.cpp +++ b/rogueviz/ru/globals.cpp @@ -59,7 +59,7 @@ enum eWall { wAir, wWall, wBouncy, wSpike, wWater, wFrozen, wDoor, wSmashedDoor, wLockedDoor, wFountain, wBluePortal, wOrangePortal, wPlatform, wStaircase, wColumn, wForge, wWoodWall, wShopDoor, wSecretPassage, wSign, wWallSign, wTimeDoor, - wBottomSpike, wRogueWallHidden, wRogueWall, wGUARD }; + wBottomSpike, wRogueWallHidden, wRogueWall, wRightSlope, wLeftSlope, wGUARD }; flagtype W_BLOCK = 1; flagtype W_TRANS = 2; @@ -71,6 +71,7 @@ flagtype W_FROZEN = 64; flagtype W_BLOCKBIRD = 128; flagtype W_STABLE = 256; flagtype W_DOWNWARD = 512; +flagtype W_SLOPE = 1024; constexpr int qwall = int(wGUARD); @@ -100,6 +101,8 @@ ruwall walls[qwall] = { {"bottom spike", "v", 0xC08080FF, W_TRANS | W_PAIN | W_BLOCKBIRD | W_DOWNWARD, "A downward-pointing spike. You can fall from above through it safely, but otherwise, it is very dangerous."}, {"wall", "#", 0xFFFFFFFF, W_BLOCK | W_STABLE, "These kinds of tough walls can never be destroyed."}, {"fake wall", "#", 0x404080FF, W_PLATFORM | W_STABLE | W_BLOCKBIRD, "Your rogueish senses have discovered that this wall is fake."}, + {"right slope", "/", 0xFFFFFFFF, W_STABLE | W_SLOPE, "Slope here."}, + {"left slope", "\\", 0xFFFFFFFF, W_STABLE | W_SLOPE, "Slope here."}, }; int sel = 1; diff --git a/rogueviz/ru/map.ru b/rogueviz/ru/map.ru index 132e2c91..eb76792b 100644 --- a/rogueviz/ru/map.ru +++ b/rogueviz/ru/map.ru @@ -2588,9 +2588,9 @@ MAP ##################...#######............###..........########....############### ##################...#######...######...###..........########....############### ##################...#######...######...###..........########....############### -##################...............................................############### -##################...............................................############### -##################...............................................############### +##################...............................................###########.... +##################.............................................................. +##################.............................................................. ############################################----################################ ############################################...A################################ #b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b..A.#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b @@ -2686,3 +2686,52 @@ VISION 8080FFFF Dancient blue dragon A huge lightning-breathing reptile. Run away! OK + +MOVE 4 Guinea Pig Pen +ROOM Slope Test +# wall +. air +/ right slope +\ left slope +MAP +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ +##################......................######################################## +#################.......................######################################## +################........................######################################## +###############......./###########\..........################################### +##############.......//###########\\.........################################### +#############.......//###########..\\........################################### +############.......//###########....\\.......################################### +###########.......//#################\########################################## +##########.......//############################################################# +#########.......//############################################################## +########.......//############################################################### +#######.......//################################################################ +.............//################################################################# +............//################################################################## +...........//################################################################### +###########/#################################################################### +################################################################################ +#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b +################################################################################ +#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b +################################################################################ +#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b +OK diff --git a/rogueviz/ru/randeff.cpp b/rogueviz/ru/randeff.cpp index b2cdc14f..d45addd0 100644 --- a/rogueviz/ru/randeff.cpp +++ b/rogueviz/ru/randeff.cpp @@ -183,7 +183,7 @@ void assign_potion_powers() { using relist = vector; find_power("health").randeffs = relist{ pick(&health_heal, &health_regen, &health_protect), random_powers[0] }; find_power("the thief").randeffs = relist{ pick(&trap_detect, &trap_snake, &trap_disarm, &trap_detect_cross), random_powers[1] }; - find_power("polymorph").randeffs = relist{ pick(&morph_cat, &morph_capy), random_powers[2], &hallux }; + find_power("polymorph").randeffs = relist{ pick(&morph_cat, &morph_capy), random_powers[2] }; find_power("reach").randeffs = relist{ pick(&jump_double, &jump_high, &jump_bubble, &jump_light), random_powers[3] }; find_power("fire").randeffs = relist{ pick(&fire_spit, &fire_weapon), random_powers[4] }; find_power("mystery").randeffs = relist{ random_powers[5], random_powers[6], random_powers[7] }; diff --git a/rogueviz/ru/render.cpp b/rogueviz/ru/render.cpp index cc8784a3..6212cb20 100644 --- a/rogueviz/ru/render.cpp +++ b/rogueviz/ru/render.cpp @@ -209,6 +209,8 @@ void init_scales() { letterscales['F'] = euscale(2.1, 1.3); letterscales['C'] = euscale(1.8, 1.3); letterscales['f'] = euscale(2.5, 1.3); + letterscales['/'] = euscale(4, 1.2); + letterscales['\\'] = euscale(4, 1.2); } void asciiletter(ld minx, ld miny, ld maxx, ld maxy, const string& ch, color_t col) {