mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
nilrider:: can now fly off surface
This commit is contained in:
parent
04b8287dbe
commit
448c08e925
@ -389,6 +389,8 @@ void level::init() {
|
|||||||
start.where = mappt(startx+.5, starty+.5, 1);
|
start.where = mappt(startx+.5, starty+.5, 1);
|
||||||
start.t = 0;
|
start.t = 0;
|
||||||
start.timer = 0;
|
start.timer = 0;
|
||||||
|
start.on_surface = this;
|
||||||
|
start.sstime = -100;
|
||||||
current = start;
|
current = start;
|
||||||
println(hlog, "start.where = ", start.where);
|
println(hlog, "start.where = ", start.where);
|
||||||
println(hlog, "current.where = ", current.where, " : ", hr::format("%p", ¤t));
|
println(hlog, "current.where = ", current.where, " : ", hr::format("%p", ¤t));
|
||||||
|
@ -11,9 +11,16 @@ struct timestamp {
|
|||||||
ld heading_angle; /**< the current heading angle */
|
ld heading_angle; /**< the current heading angle */
|
||||||
ld vel; /**< the current velocity in units per second */
|
ld vel; /**< the current velocity in units per second */
|
||||||
ld circpos; /**< controls the wheel graphics */
|
ld circpos; /**< controls the wheel graphics */
|
||||||
ld slope; /**< the current slope */
|
ld slope; /**< the current slope, as angle */
|
||||||
|
ld chg_slope; /**< slope used at surface state change */
|
||||||
|
ld gfx_slope; /**< current slope used by graphics */
|
||||||
ld t; /**< planning spline parameter */
|
ld t; /**< planning spline parameter */
|
||||||
ld timer = 0; /**< the timer, in seconds */
|
ld timer = 0; /**< the timer, in seconds */
|
||||||
|
level *on_surface;/**< pointer to the sub-level if we are currently on the surface, nullptr otherwise */
|
||||||
|
|
||||||
|
ld sstime; /**< when did we leave or enter surface? for smoothing gfx_slope */
|
||||||
|
hyperpoint flyvel;/**< velocity vector if we are not on any surface */
|
||||||
|
ld circvel; /**< how fast the wheel is rotating if we are not on any surface, per second */
|
||||||
|
|
||||||
flagtype collected_triangles; /**< a bitset which shows which triangles are collected */
|
flagtype collected_triangles; /**< a bitset which shows which triangles are collected */
|
||||||
flagtype goals; /**< a bitset which shows which goals are complete */
|
flagtype goals; /**< a bitset which shows which goals are complete */
|
||||||
@ -25,6 +32,7 @@ struct timestamp {
|
|||||||
void draw_instruments(level*);
|
void draw_instruments(level*);
|
||||||
ld energy_in_squares();
|
ld energy_in_squares();
|
||||||
bool collect(level*);
|
bool collect(level*);
|
||||||
|
bool out_of_surface(level*);
|
||||||
void be_consistent();
|
void be_consistent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,10 +82,16 @@ void timestamp::draw_unilcycle(const shiftmatrix& V) {
|
|||||||
|
|
||||||
bool tick_debug = false;
|
bool tick_debug = false;
|
||||||
|
|
||||||
|
bool timestamp::out_of_surface(level *lev) {
|
||||||
|
auto xy = lev->get_xy_i(where);
|
||||||
|
char ch = lev->mapchar(xy);
|
||||||
|
return ch == '!';
|
||||||
|
}
|
||||||
|
|
||||||
bool timestamp::collect(level *lev) {
|
bool timestamp::collect(level *lev) {
|
||||||
auto xy = lev->get_xy_i(where);
|
auto xy = lev->get_xy_i(where);
|
||||||
char ch = lev->mapchar(xy);
|
char ch = lev->mapchar(xy);
|
||||||
if(ch == 'r' || ch == '!') return false;
|
if(ch == 'r') return false;
|
||||||
if(ch == '*') {
|
if(ch == '*') {
|
||||||
for(int i=0; i<isize(lev->triangles); i++) {
|
for(int i=0; i<isize(lev->triangles); i++) {
|
||||||
auto& t = lev->triangles[i];
|
auto& t = lev->triangles[i];
|
||||||
@ -143,30 +149,63 @@ void timestamp::be_consistent() {
|
|||||||
|
|
||||||
bool timestamp::tick(level *lev) {
|
bool timestamp::tick(level *lev) {
|
||||||
|
|
||||||
if(!collect(lev)) return false;
|
if(on_surface && !collect(lev)) return false;
|
||||||
const ld eps = slope_eps;
|
const ld eps = slope_eps;
|
||||||
|
|
||||||
hyperpoint wnext = where;
|
if(on_surface) {
|
||||||
wnext[0] += cos(heading_angle) * eps;
|
hyperpoint wnext = where;
|
||||||
wnext[1] += sin(heading_angle) * eps;
|
wnext[0] += cos(heading_angle) * eps;
|
||||||
wnext[2] = lev->surface(wnext);
|
wnext[1] += sin(heading_angle) * eps;
|
||||||
|
wnext[2] = lev->surface(wnext);
|
||||||
|
|
||||||
wnext = gpushxto0(where) * wnext;
|
wnext = gpushxto0(where) * wnext;
|
||||||
slope = atan(wnext[2] / eps);
|
slope = atan(wnext[2] / eps);
|
||||||
|
|
||||||
auto ovel = vel;
|
if(out_of_surface(lev)) {
|
||||||
|
on_surface = nullptr;
|
||||||
vel -= sin(slope) * gravity / tps;
|
sstime = timer; chg_slope = gfx_slope;
|
||||||
if(vel < 0) {
|
flyvel = wnext * vel / hypot_d(3, wnext);
|
||||||
vel = 0;
|
flyvel[3] = 0;
|
||||||
if(ovel == 0) return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mvel = (vel + ovel) / 2;
|
if(on_surface) {
|
||||||
where[0] += cos(heading_angle) * mvel * cos(slope) / tps;
|
auto ovel = vel;
|
||||||
where[1] += sin(heading_angle) * mvel * cos(slope) / tps;
|
|
||||||
where[2] = lev->surface(where);
|
vel -= sin(slope) * gravity / tps;
|
||||||
circpos += mvel / whrad / tps;
|
if(vel < 0) {
|
||||||
|
vel = 0;
|
||||||
|
if(ovel == 0) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mvel = (vel + ovel) / 2;
|
||||||
|
where[0] += cos(heading_angle) * mvel * cos(slope) / tps;
|
||||||
|
where[1] += sin(heading_angle) * mvel * cos(slope) / tps;
|
||||||
|
where[2] = lev->surface(where);
|
||||||
|
circvel = mvel / whrad;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
auto oflyvel = flyvel;
|
||||||
|
flyvel = rgpushxto0(where) * flyvel;
|
||||||
|
flyvel[2] -= gravity / tps / 2;
|
||||||
|
|
||||||
|
// todo rewrite geodesic_step to take gravity into account into RK4 correctly
|
||||||
|
flyvel /= tps;
|
||||||
|
nisot::geodesic_step(where, flyvel);
|
||||||
|
flyvel *= tps;
|
||||||
|
|
||||||
|
flyvel[2] -= gravity / tps / 2;
|
||||||
|
auto mflyvel = (flyvel + oflyvel) / 2;
|
||||||
|
heading_angle = atan2(mflyvel[1], mflyvel[0]);
|
||||||
|
flyvel = gpushxto0(where) * flyvel;
|
||||||
|
mflyvel = gpushxto0(where) * mflyvel;
|
||||||
|
slope = atan(mflyvel[2] / hypot_d(2, mflyvel));
|
||||||
|
|
||||||
|
vel = hypot_d(3, flyvel);
|
||||||
|
}
|
||||||
|
|
||||||
|
circpos += circvel / tps;
|
||||||
|
|
||||||
timer += 1. / tps;
|
timer += 1. / tps;
|
||||||
return true;
|
return true;
|
||||||
@ -195,7 +234,8 @@ void timestamp::centerview(level *lev) {
|
|||||||
|
|
||||||
transmatrix T = View;
|
transmatrix T = View;
|
||||||
|
|
||||||
ld gfx_slope = binsearch(-90*degree, min(slope, min_gfx_slope), [&] (ld slope) {
|
gfx_slope = min_gfx_slope;
|
||||||
|
if(on_surface) gfx_slope = binsearch(-90*degree, min(slope, min_gfx_slope), [&] (ld slope) {
|
||||||
View = T;
|
View = T;
|
||||||
rotate_view(cspin(1, 2, slope));
|
rotate_view(cspin(1, 2, slope));
|
||||||
for(int i=0; i<8; i++) {
|
for(int i=0; i<8; i++) {
|
||||||
@ -209,6 +249,11 @@ void timestamp::centerview(level *lev) {
|
|||||||
return false;
|
return false;
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
|
if(timer < sstime + 1) {
|
||||||
|
ld t = timer - sstime;
|
||||||
|
gfx_slope = lerp(chg_slope, gfx_slope, t * t * (3 - 2*t));
|
||||||
|
}
|
||||||
|
|
||||||
View = T;
|
View = T;
|
||||||
rotate_view(cspin(1, 2, gfx_slope));
|
rotate_view(cspin(1, 2, gfx_slope));
|
||||||
shift_view(ztangent(whdist * lev->scale));
|
shift_view(ztangent(whdist * lev->scale));
|
||||||
|
Loading…
Reference in New Issue
Block a user