diff --git a/rogueviz/nilrider/nilrider.cpp b/rogueviz/nilrider/nilrider.cpp index d695999e..e5057a84 100644 --- a/rogueviz/nilrider/nilrider.cpp +++ b/rogueviz/nilrider/nilrider.cpp @@ -168,6 +168,7 @@ bool turn(int delta) { } void main_menu(); +void layer_selection_screen(); #define PSEUDOKEY_PAUSE 2511 #define PSEUDOKEY_SIM 2512 @@ -221,6 +222,9 @@ void run() { if(planning_mode && !view_replay) { for(auto& b: buttons) show_button(b.first, b.second, planmode == b.first ? 0xFFD500 : dialog::dialogcolor); show_button(PSEUDOKEY_SIM, "simulation"); + if(curlev->sublevels.size() && layer_edited) { + show_button('L', "layer: " + layer_edited->name); + } } bool pause_av = view_replay || !planning_mode; @@ -248,6 +252,10 @@ void run() { dialog::add_key_action(PSEUDOKEY_SIM, toggle_replay); dialog::display(); + if(planning_mode && !view_replay && curlev->sublevels.size()) { + dialog::add_key_action('L', [] { pushScreen(layer_selection_screen); }); + } + int* t = scfg_nilrider.keyaction; for(int i=1; i<512; i++) { auto& ka = dialog::key_actions; @@ -291,6 +299,20 @@ void pick_level() { dialog::display(); } +void layer_selection_screen() { + poly_outline = 0xFF; + dialog::init(XLAT("layer selection"), 0xC0C0FFFF, 150, 100); + dialog::addBreak(50); + auto layers = curlev->gen_layer_list(); + char key = 'a'; + for(auto l: layers) { + dialog::addBoolItem(l->name, l == layer_edited, key++); + dialog::add_action([l] { layer_edited = l; popScreen(); }); + } + dialog::addBack(); + dialog::display(); + } + void pick_game() { clearMessages(); dialog::init(); diff --git a/rogueviz/nilrider/planning.cpp b/rogueviz/nilrider/planning.cpp index aad98bf6..075bb2dc 100644 --- a/rogueviz/nilrider/planning.cpp +++ b/rogueviz/nilrider/planning.cpp @@ -2,17 +2,29 @@ namespace nilrider { hyperpoint get_spline(ld t); +level *layer_edited; + bool level::simulate() { loaded_or_planned = true; if(history.empty()) history.push_back(start); auto at = history.back(); - + if(at.t >= isize(plan) - 1.001) return false; ld goal_t; + + if(at.on_surface && isize(history) >= 2 && !history[isize(history)-2].on_surface) { + int index = ceil(history[isize(history)-2].t)+1; + if(index >= isize(plan)) { + return false; + } + plan[index].at = at.where; + history.back().t = at.t = index; + if(index == isize(plan) - 1) return false; + } - if(1) { + if(at.on_surface) { int steps = 20; ld min_t, max_t; @@ -47,16 +59,22 @@ bool level::simulate() { } goal_t = (min_t + max_t) / 2; - } - hyperpoint h = get_spline(goal_t); - at.heading_angle = atan2(h[1] - at.where[1], h[0] - at.where[0]); - history.back() = at; - - at.be_consistent(); - if(!at.tick(this)) return false; - at.t = goal_t; - history.push_back(at); + hyperpoint h = get_spline(goal_t); + at.heading_angle = atan2(h[1] - at.where[1], h[0] - at.where[0]); + + history.back() = at; + at.be_consistent(); + if(!at.tick(this)) { println(hlog, "tick returns false"); return false; } + at.t = goal_t; + history.push_back(at); + } + else { + at.be_consistent(); + if(at.where[2] <= surface(at.where) - 100) { println(hlog, "fall"); return false; } + if(!at.tick(this)) { println(hlog, "crash"); return false; } + history.push_back(at); + } return true; } @@ -95,6 +113,8 @@ void level::compute_plan_transform() { bool restored = false; +int plan_precision = 50; + void level::draw_planning_screen() { if(just_refreshing) return; @@ -104,13 +124,14 @@ void level::draw_planning_screen() { new_levellines_for = mousept = current.where; } curlev->init_textures(); + for(auto lay: gen_layer_list()) lay->init_textures(); dynamicval g(geometry, gEuclid); dynamicval pm(pmodel, mdDisk); dynamicval ga(vid.always3, false); dynamicval gi(ginf[gEuclid].g, giEuclid2); check_cgi(); cgi.require_shapes(); - curlev->init_shapes(); + for(auto lay: gen_layer_list()) lay->init_shapes(); initquickqueue(); if(recompute_plan_transform) { @@ -131,10 +152,20 @@ void level::draw_planning_screen() { box = inHighQual ? scr_to_map(hpxy(10, 0))[0] - scr_to_map(hpxy(0,0))[0] : scr_to_map(hpxy(mousex + 5, mousey))[0] - mousept[0]; - /* draw the map */ - auto& p = queuepolyat(T, shPlanFloor, 0xFFFFFFFF, PPR::FLOOR); - p.tinf = &uniltinf; - uniltinf.texture_id = unil_texture_levels->textureid; + auto draw_layer = [&] (level *l, color_t col) { + auto& p = queuepolyat(T, l->shPlanFloor, col, PPR::FLOOR); + p.tinf = &l->uniltinf; + l->uniltinf.texture_id = l->unil_texture_levels->textureid; + }; + + bool layer_found = false; + auto layers = gen_layer_list(); + for(auto l: layers) { + if(l == layer_edited) layer_found = true; + else draw_layer(l, 0x808080FF); + } + if(!layer_found) layer_edited = this; + draw_layer(layer_edited, 0xFFFFFFFF); auto draw_sq = [&] (hyperpoint h, color_t col, PPR prio) { curvepoint(hpxy(h[0]+box, h[1]+box)); @@ -162,41 +193,45 @@ void level::draw_planning_screen() { draw_line(pp.at - pp.vel, pp.at + pp.vel, 0x80, PPR::BFLOOR); } - bool after = false; - if(history.empty()) history.push_back(start); - closest_t = history.back().t; - ld closest_dist = box * 2; - vid.linewidth *= 3; + int ps = isize(plan); for(int t=0; t<=100*(ps-1); t++) { - ld tt = t / 100.; - if(tt > history.back().t && !after) { - queuecurve(T, 0xFFFFFFC0, 0, PPR::LIZEYE); - after = true; - } - hyperpoint h = get_spline(tt); + hyperpoint h = get_spline(t / 100.); curvepoint(hpxy(h[0], h[1])); - ld dist = sqhypot_d(2, h - mousept); - if(dist < closest_dist) closest_dist = dist, closest_t = tt; - } - queuecurve(T, after ? 0xFF8080C0 : 0xFFFFFFC0, 0, PPR::LIZEYE); - vid.linewidth /= 3; - - if(!history.empty()) { - int mint = 0, maxt = isize(history)-1; - while(mint < maxt) { - int t = (mint + maxt + 1) / 2; - if(history[t].t > closest_t) maxt = t-1; - else mint = t; - } - - current = history[mint]; } + queuecurve(T, 0xFF8080C0, 0, PPR::LIZEYE); + vid.linewidth /= 3; - draw_sq(get_spline(closest_t), 0x8080FFFF, PPR::ITEM); + closest_t = history.back().t; + ld closest_dist = box * 2; + current = history.back(); + + vid.linewidth *= 3; + level *current_surface = this; + auto surface_color = [&] () -> color_t { + if(current_surface == layer_edited) return 0xFFFFFFFF; + if(current_surface) return 0x101010FF; + return 0xFF00FFFF; + }; + for(int i=0; i