1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-01-23 15:36:59 +00:00

nilrider:: edit plans for multi-layer levels

This commit is contained in:
Zeno Rogue 2024-08-19 12:25:02 +02:00
parent cab4d05f5f
commit b3ce3cd2d8
2 changed files with 100 additions and 43 deletions

View File

@ -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();

View File

@ -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<eGeometry> g(geometry, gEuclid);
dynamicval<eModel> pm(pmodel, mdDisk);
dynamicval<bool> ga(vid.always3, false);
dynamicval<geometryinfo1> 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<isize(history);) {
auto& hi = history[i];
auto& h = hi.where;
curvepoint(hpxy(h[0], h[1]));
if(hi.on_surface != current_surface) {
queuecurve(T, surface_color(), 0, PPR::LIZEYE);
current_surface = hi.on_surface;
curvepoint(hpxy(h[0], h[1]));
}
i++; if(i < isize(history)) i = min(i + plan_precision - 1, isize(history)-1);
ld dist = sqhypot_d(2, h - mousept);
if(dist < closest_dist) closest_dist = dist, current = history[i];
}
queuecurve(T, surface_color(), 0, PPR::LIZEYE);
vid.linewidth /= 3;
draw_sq(current.where, 0xFF8000FF, PPR::ITEM);
draw_sq(mousept, 0x8080FFFF, PPR::ITEM);