mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
ads-game:: underlying/spacetime views
This commit is contained in:
parent
a7ca4c2902
commit
45141a9df0
@ -39,6 +39,7 @@ namespace rogueviz { std::vector<hr::reaction_t> cleanup; }
|
||||
#include "menu.cpp"
|
||||
#include "ds-game.cpp"
|
||||
#include "ds-texture.cpp"
|
||||
#include "underlying.cpp"
|
||||
|
||||
namespace hr {
|
||||
|
||||
@ -101,6 +102,7 @@ void run_ads_game() {
|
||||
rogueviz::rv_hook(hooks_frame, 100, view_ads_game);
|
||||
rogueviz::rv_hook(hooks_prestats, 100, display_rsrc);
|
||||
rogueviz::rv_hook(hooks_handleKey, 0, handleKey);
|
||||
rogueviz::rv_hook(hooks_drawcell, 0, ads_draw_cell);
|
||||
rogueviz::rv_hook(shmup::hooks_turn, 0, ads_turn);
|
||||
rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation);
|
||||
|
||||
|
@ -17,7 +17,7 @@ struct cell_to_draw {
|
||||
};
|
||||
|
||||
void draw_game_cell(const cell_to_draw& cd) {
|
||||
|
||||
bool hv = rotspace;
|
||||
using cellptr = cell*;
|
||||
const cellptr& c = cd.c;
|
||||
const ads_matrix& V = cd.V;
|
||||
@ -36,12 +36,15 @@ void draw_game_cell(const cell_to_draw& cd) {
|
||||
if(!gen_budget) return;
|
||||
gen_budget--;
|
||||
}
|
||||
gen_terrain(c, ci);
|
||||
gen_rocks(c, ci, 0);
|
||||
PIU({
|
||||
gen_terrain(c, ci);
|
||||
gen_rocks(c, ci, 0);
|
||||
});
|
||||
|
||||
auto& t = ci.type;
|
||||
|
||||
if(t == wtGate) {
|
||||
if(hv) ;
|
||||
else if(t == wtGate) {
|
||||
ld minv = hlist[0].shift;
|
||||
ld maxv = hlist[0].shift;
|
||||
for(auto& h: hlist) {
|
||||
@ -120,13 +123,28 @@ void draw_game_cell(const cell_to_draw& cd) {
|
||||
rock.pts.push_back(f);
|
||||
});
|
||||
}
|
||||
|
||||
if(hv) {
|
||||
ads_point M = current * (V * rock.at) * ads_matrix(Id, rock.pt_main.shift) * C0;
|
||||
optimize_shift(M);
|
||||
for(ld z=-5; z<=5; z+=0.2) {
|
||||
for(int i=0; i<isize(shape); i += 2) {
|
||||
auto h = rots::uxpush(shape[i] * ads_scale) * rots::uypush(shape[i+1] * ads_scale) * C0;
|
||||
curvepoint(h);
|
||||
}
|
||||
curvepoint_first();
|
||||
queuecurve(current * V * rock.at * ads_matrix(Id, rock.pt_main.shift+z), rock.col, 0, PPR::LINE);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto h: rock.pts) curvepoint(h.h);
|
||||
curvepoint(rock.pts[0].h);
|
||||
queuecurve(shiftless(Id),
|
||||
rock.type == oMissile ? missile_color :
|
||||
rock.type == oParticle ? rock.col :
|
||||
0x000000FF, rock.col, obj_prio[rock.type]);
|
||||
else {
|
||||
for(auto h: rock.pts) curvepoint(h.h);
|
||||
curvepoint(rock.pts[0].h);
|
||||
queuecurve(shiftless(Id),
|
||||
rock.type == oMissile ? missile_color :
|
||||
rock.type == oParticle ? rock.col :
|
||||
0x000000FF, rock.col, obj_prio[rock.type]);
|
||||
}
|
||||
|
||||
if(view_proper_times && rock.type != oParticle) {
|
||||
string str = format(tformat, rock.pt_main.shift / ads_time_unit);
|
||||
@ -137,6 +155,18 @@ void draw_game_cell(const cell_to_draw& cd) {
|
||||
/* todo: binary search */
|
||||
if(paused) for(auto& rock: ci.shipstates) {
|
||||
cross_result cr;
|
||||
|
||||
if(hv) {
|
||||
auto& shape = shape_ship;
|
||||
for(int i=0; i<isize(shape); i += 2) {
|
||||
auto h = rots::uxpush(shape[i] * ads_scale) * rots::uypush(shape[i+1] * ads_scale) * C0;
|
||||
curvepoint(h);
|
||||
}
|
||||
curvepoint_first();
|
||||
queuecurve(current * V * rock.at, shipcolor, 0, PPR::LINE);
|
||||
continue;
|
||||
}
|
||||
|
||||
hybrid::in_actual([&]{
|
||||
dynamicval<eGeometry> b(geometry, gRotSpace);
|
||||
auto h = V * rock.at;
|
||||
@ -164,7 +194,7 @@ void draw_game_cell(const cell_to_draw& cd) {
|
||||
}
|
||||
}
|
||||
|
||||
if(paused && c == vctr_ship && !game_over && !inHighQual) {
|
||||
if(paused && c == vctr_ship && !game_over && !in_replay && !hv) {
|
||||
cross_result cr;
|
||||
hybrid::in_actual([&]{
|
||||
auto h = ads_inverse(current_ship * vctrV_ship);
|
||||
@ -202,6 +232,8 @@ void view_footer() {
|
||||
void view_ads_game() {
|
||||
displayed.clear();
|
||||
|
||||
bool hv = hybri;
|
||||
|
||||
hybrid::in_actual([&] {
|
||||
gen_budget = max_gen_per_frame;
|
||||
|
||||
@ -284,7 +316,7 @@ void view_ads_game() {
|
||||
});
|
||||
}
|
||||
|
||||
if(!game_over && !paused && !in_replay) {
|
||||
if(!game_over && !paused && !in_replay && !hv) {
|
||||
poly_outline = 0xFF;
|
||||
if(ship_pt < invincibility_pt) {
|
||||
ld u = (invincibility_pt-ship_pt) / ads_how_much_invincibility;
|
||||
|
@ -261,6 +261,7 @@ void ds_crash_ship() {
|
||||
|
||||
void ds_handle_crashes() {
|
||||
if(paused) return;
|
||||
dynamicval<eGeometry> g(geometry, gSphere);
|
||||
vector<ads_object*> dmissiles;
|
||||
vector<ads_object*> drocks;
|
||||
vector<ads_object*> dresources;
|
||||
@ -456,10 +457,13 @@ bool invalid(cross_result& res) {
|
||||
|
||||
void view_ds_game() {
|
||||
displayed.clear();
|
||||
|
||||
draw_textures();
|
||||
|
||||
sphereflip = sphereflipped() ? MirrorZ : Id;
|
||||
bool hv = hyperbolic;
|
||||
bool hvrel = among(pmodel, mdRelPerspective, mdRelOrthogonal);
|
||||
|
||||
sphereflip = hv ? Id : sphereflipped() ? MirrorZ : Id;
|
||||
|
||||
if(!hv) draw_textures();
|
||||
|
||||
if(1) {
|
||||
for(auto& r: rocks) {
|
||||
@ -505,8 +509,39 @@ void view_ds_game() {
|
||||
|
||||
if(area > 0) continue;
|
||||
|
||||
for(auto p: rock.pts) curvepoint(p.h);
|
||||
queuecurve(shiftless(sphereflip), rock.col, rock.col, obj_prio[rock.type]);
|
||||
if(hv) {
|
||||
ld t = rock.at.shift;
|
||||
if(rock.type == oMainRock) t = floor(10*t + .5) / 10;
|
||||
transmatrix at = current.T * lorentz(2, 3, t - current.shift) * rock.at.T;
|
||||
for(ld s=-3; s<=3; s+=0.1) {
|
||||
transmatrix at1 = at * lorentz(2, 3, s);
|
||||
if((at1 * pov) [2] < 0) continue;
|
||||
|
||||
auto& sh = *rock.shape;
|
||||
|
||||
for(int i=0; i<isize(sh); i+=2) {
|
||||
hyperpoint h = hvrel ? tpt(sh[i], sh[i+1]) * pov: hpxy(sh[i], sh[i+1]);
|
||||
curvepoint(h);
|
||||
}
|
||||
curvepoint_first();
|
||||
color_t col = rock.col;
|
||||
if(col == 0xFF) col = 0xFFD500FF;
|
||||
if(col != 0xFFD500FF && !hvrel) part(col, 0) = part(col, 0) / 4;
|
||||
queuecurve(shiftless(at1), col, 0, PPR::TRANSPARENT_WALL);
|
||||
}
|
||||
}
|
||||
|
||||
if(!hv) {
|
||||
for(auto p: rock.pts) curvepoint(p.h);
|
||||
queuecurve(shiftless(sphereflip), rock.col, rock.col, obj_prio[rock.type]);
|
||||
}
|
||||
|
||||
if(pmodel == mdPerspective) {
|
||||
for(auto p: rock.pts) curvepoint(p.h);
|
||||
curvepoint_first();
|
||||
color_t col = rock.col; part(col, 0) /= 2;
|
||||
queuecurve(shiftless(sphereflip), col, 0, obj_prio[rock.type]).flags |= POLY_NO_FOG;
|
||||
}
|
||||
|
||||
if(view_proper_times && rock.type != oParticle) {
|
||||
ld t = rock.pt_main.shift;
|
||||
@ -524,6 +559,19 @@ void view_ds_game() {
|
||||
if(paused) for(auto& ss: history) {
|
||||
if(ss.at.shift < current.shift - 4 * TAU) continue;
|
||||
if(ss.at.shift > current.shift + 4 * TAU) continue;
|
||||
|
||||
auto& shape = shape_ship;
|
||||
|
||||
if(hv) {
|
||||
for(int i=0; i<isize(shape); i+=2) {
|
||||
hyperpoint h = hvrel ? tpt(shape[i], shape[i+1]) * pov: hpxy(shape[i], shape[i+1]);
|
||||
curvepoint(h);
|
||||
}
|
||||
curvepoint_first();
|
||||
queuecurve(shiftless(current.T * lorentz(2, 3, ss.at.shift - current.shift) * ss.at.T), shipcolor, 0, PPR::TRANSPARENT_WALL);
|
||||
continue;
|
||||
}
|
||||
|
||||
dynamicval<eGeometry> g(geometry, gSpace435);
|
||||
cross_result cr = ds_cross0(current.T * lorentz(2, 3, ss.at.shift - current.shift) * ss.at.T);
|
||||
if(cr.shift < delta) continue;
|
||||
@ -532,15 +580,22 @@ void view_ds_game() {
|
||||
|
||||
vector<hyperpoint> pts;
|
||||
|
||||
auto& shape = shape_ship;
|
||||
for(int i=0; i<isize(shape); i += 2) {
|
||||
transmatrix at1 = at * tpt(shape[i], shape[i+1]);
|
||||
pts.push_back(ds_cross0(at1).h);
|
||||
}
|
||||
|
||||
geometry = g.backup;
|
||||
for(auto pt: pts) curvepoint(pt);
|
||||
queuecurve(shiftless(sphereflip), 0xFF, shipcolor, PPR::MONSTER_FOOT);
|
||||
|
||||
if(!hv) {
|
||||
for(auto pt: pts) curvepoint(pt);
|
||||
queuecurve(shiftless(sphereflip), 0xFF, shipcolor, PPR::MONSTER_FOOT);
|
||||
}
|
||||
|
||||
if(pmodel == mdPerspective) {
|
||||
for(auto pt: pts) curvepoint(pt);
|
||||
queuecurve(shiftless(sphereflip), 0xFF, shipcolor, PPR::MONSTER_FOOT).flags |= POLY_NO_FOG;
|
||||
}
|
||||
|
||||
if(view_proper_times) {
|
||||
string str = format(tformat, (cr.shift + ss.start) / ds_time_unit);
|
||||
@ -554,7 +609,17 @@ void view_ds_game() {
|
||||
ld u = (invincibility_pt-ship_pt) / ds_how_much_invincibility;
|
||||
poly_outline = gradient(shipcolor, rsrc_color[rtHull], 0, 0.5 + cos(5*u*TAU), 1);
|
||||
}
|
||||
queuepolyat(shiftless(sphereflip * spin(ang*degree)), make_shape(), shipcolor, PPR::MONSTER_HAIR);
|
||||
if(hv) {
|
||||
auto& shape = shape_ship;
|
||||
for(int i=0; i<isize(shape); i += 2) {
|
||||
transmatrix at1 = tpt(shape[i], shape[i+1]);
|
||||
curvepoint(ds_cross0(at1).h);
|
||||
}
|
||||
queuecurve(shiftless(sphereflip * spin(ang*degree)), shipcolor, 0, PPR::MONSTER_HAIR).flags |= POLY_NO_FOG;
|
||||
}
|
||||
else {
|
||||
queuepolyat(shiftless(sphereflip * spin(ang*degree)), make_shape(), shipcolor, PPR::MONSTER_HAIR);
|
||||
}
|
||||
poly_outline = 0xFF;
|
||||
|
||||
if(view_proper_times) {
|
||||
@ -568,7 +633,7 @@ void view_ds_game() {
|
||||
queuestr(shiftless(sphereflip), .1, str, 0xFFFF00, 8);
|
||||
}
|
||||
|
||||
if(paused && !game_over && !in_replay) {
|
||||
if(paused && !game_over && !in_replay && !hv) {
|
||||
vector<hyperpoint> pts;
|
||||
int ok = 0, bad = 0;
|
||||
for(int i=0; i<=360; i++) {
|
||||
@ -606,30 +671,6 @@ void ds_restart() {
|
||||
init_rsrc();
|
||||
}
|
||||
|
||||
void replay_animation() {
|
||||
if(!in_replay) return;
|
||||
view_pt = (ticks / 1000.) * DS_(simspeed);
|
||||
ld maxt = history.back().start + 0.001;
|
||||
view_pt -= maxt * floor(view_pt / maxt);
|
||||
for(auto& ss: history)
|
||||
if(ss.start + ss.duration > view_pt) {
|
||||
current = ss.current;
|
||||
if(sphere) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace435);
|
||||
current.T = inverse(ss.at.T * spin(-(ss.ang+90)*degree));
|
||||
current.T = lorentz(3, 2, view_pt - ss.start) * current.T;
|
||||
}
|
||||
else PIA({
|
||||
vctr = new_vctr = ss.vctr;
|
||||
vctrV = new_vctrV = ss.vctrV;
|
||||
current.T = cspin(3, 2, view_pt - ss.start) * current.T;
|
||||
if(auto_rotate)
|
||||
current.T = cspin(1, 0, view_pt - ss.start) * current.T;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void run_ds_game() {
|
||||
|
||||
stop_game();
|
||||
@ -648,19 +689,8 @@ void run_ds_game() {
|
||||
rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation);
|
||||
}
|
||||
|
||||
void switch_replay() {
|
||||
in_replay = !in_replay;
|
||||
if(in_replay) {
|
||||
paused = true;
|
||||
anims::period = 1000. * history.back().start / DS_(simspeed);
|
||||
anims::noframes = anims::period * 60 / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
auto ds_hooks =
|
||||
arg::add3("-ds-game", run_ds_game)
|
||||
+ arg::add3("-ds-recenter", [] { current = Id; })
|
||||
+ arg::add3("-ds-record", switch_replay);
|
||||
arg::add3("-ds-game", run_ds_game);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -128,5 +128,9 @@ void run_ds_game();
|
||||
/** in the replay mode */
|
||||
bool in_replay;
|
||||
void switch_replay();
|
||||
void replay_animation();
|
||||
|
||||
void switch_underlying();
|
||||
bool ads_draw_cell(cell *c, const shiftmatrix& V);
|
||||
|
||||
}}
|
||||
|
@ -247,6 +247,11 @@ void ads_crash_ship() {
|
||||
|
||||
void handle_crashes() {
|
||||
if(paused) return;
|
||||
if(rotspace) {
|
||||
if(!currentmap) { println(hlog, "no currentmap!"); return; }
|
||||
PIU({ handle_crashes(); });
|
||||
return;
|
||||
}
|
||||
vector<ads_object*> missiles;
|
||||
vector<ads_object*> rocks;
|
||||
vector<ads_object*> resources;
|
||||
|
163
rogueviz/ads/views.cpp
Normal file
163
rogueviz/ads/views.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/* underlying/spacetime views, and also replaying */
|
||||
|
||||
namespace hr {
|
||||
|
||||
namespace ads_game {
|
||||
|
||||
hrmap *map_hyp;
|
||||
|
||||
bool hv_klein = false;
|
||||
|
||||
transmatrix Duality;
|
||||
|
||||
void switch_underlying() {
|
||||
clearMessages();
|
||||
|
||||
if(main_rock) {
|
||||
|
||||
if(sphere) {
|
||||
cgi.use_count++;
|
||||
geometry = gSpace435;
|
||||
variation = eVariation::pure;
|
||||
swap(currentmap, map_hyp);
|
||||
pmodel = hv_klein ? mdDisk : mdPerspective;
|
||||
if(hv_klein) pconf.alpha = 0;
|
||||
check_cgi();
|
||||
cgi.require_basics();
|
||||
cgi.use_count++;
|
||||
|
||||
initcells();
|
||||
initgame();
|
||||
nomap = false;
|
||||
}
|
||||
|
||||
else if(hyperbolic) {
|
||||
nomap = true;
|
||||
geometry = gSphere;
|
||||
variation = eVariation::bitruncated;
|
||||
swap(currentmap, map_hyp);
|
||||
pmodel = mdDisk;
|
||||
check_cgi();
|
||||
nomap = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
check_cgi();
|
||||
cgi.use_count++;
|
||||
if(hyperbolic) {
|
||||
hybrid::switch_to_actual();
|
||||
pmodel = mdRelPerspective;
|
||||
hyperpoint res;
|
||||
nomap = false;
|
||||
nonisotropic_weird_transforms = true;
|
||||
NLP = Id;
|
||||
/* Duality = Id;
|
||||
for(int a=0; a<4; a++) for(int b=0; b<4; b++) Duality[a][b] = (a^2) == b; */
|
||||
}
|
||||
|
||||
else if(hybri) {
|
||||
hybrid::switch_to_underlying();
|
||||
pmodel = mdDisk;
|
||||
nomap = true;
|
||||
}
|
||||
cgi.use_count++;
|
||||
}
|
||||
|
||||
View = Id;
|
||||
cwt = centerover = currentmap->gamestart();
|
||||
}
|
||||
|
||||
bool ads_draw_cell(cell *c, const shiftmatrix& V) {
|
||||
auto cur_w = hybrid::get_where(c);
|
||||
auto& ci = ci_at[cur_w.first];
|
||||
if(ci.type) {
|
||||
c->wall = waWaxWall;
|
||||
c->landparam =
|
||||
ci.type == wtSolid ? 0x603000 :
|
||||
ci.type == wtDestructible ? 0x301800 :
|
||||
0x080828;
|
||||
}
|
||||
else {
|
||||
c->wall = waNone;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void replay_animation() {
|
||||
if(in_replay) {
|
||||
view_pt = (ticks / 1000.) * DS_(simspeed);
|
||||
ld maxt = history.back().start + 0.001;
|
||||
view_pt -= maxt * floor(view_pt / maxt);
|
||||
for(auto& ss: history)
|
||||
if(ss.start + ss.duration > view_pt) {
|
||||
current = ss.current;
|
||||
if(main_rock) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace435);
|
||||
current.T = inverse(ss.at.T * spin(-(ss.ang)*degree));
|
||||
current.T = lorentz(3, 2, view_pt - ss.start) * current.T;
|
||||
}
|
||||
else PIA({
|
||||
vctr = new_vctr = ss.vctr;
|
||||
vctrV = new_vctrV = ss.vctrV;
|
||||
current.T = cspin(3, 2, view_pt - ss.start) * current.T;
|
||||
if(auto_rotate)
|
||||
current.T = cspin(1, 0, view_pt - ss.start) * current.T;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(main_rock && hyperbolic) {
|
||||
View = Id;
|
||||
centerover = currentmap->gamestart();
|
||||
ld s = current.shift;
|
||||
while(s > +1) { View = lorentz(2, 3, -1) * View; optimizeview(); s--; }
|
||||
while(s < -1) { View = lorentz(2, 3, 1) * View; optimizeview(); s++; }
|
||||
View = current.T * lorentz(2, 3, -s) * View; optimizeview();
|
||||
centerover->wall = waNone;
|
||||
}
|
||||
|
||||
if(!main_rock && rotspace) {
|
||||
check_cgi();
|
||||
|
||||
ads_matrix CV = current * vctrV;
|
||||
centerover = hybrid::get_at(vctr, 0);
|
||||
|
||||
View = Id;
|
||||
|
||||
// chg_shift(CV.shift) * CV.T
|
||||
|
||||
auto sub_optimizeview = [&] {
|
||||
/* the important difference from optimizeview() is that we do not try to fix */
|
||||
transmatrix iView = inverse(View);
|
||||
virtualRebase(centerover, iView);
|
||||
View = inverse(iView);
|
||||
};
|
||||
|
||||
ld s = CV.shift;
|
||||
View = CV.T * View; optimizeview();
|
||||
while(s > 1) { View = chg_shift(1) * View; sub_optimizeview(); s--; }
|
||||
while(s < -1) { View = chg_shift(-1) * View; sub_optimizeview(); s++; }
|
||||
View = chg_shift(s) * View; sub_optimizeview();
|
||||
|
||||
centerover->wall = waNone;
|
||||
}
|
||||
}
|
||||
|
||||
void switch_replay() {
|
||||
in_replay = !in_replay;
|
||||
if(in_replay) {
|
||||
paused = true;
|
||||
anims::period = 1000. * history.back().start / DS_(simspeed);
|
||||
anims::noframes = anims::period * 60 / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
auto view_hooks =
|
||||
+ arg::add3("-ds-recenter", [] { current = Id; })
|
||||
+ arg::add3("-ds-record", switch_replay)
|
||||
+ arg::add3("-ds-switchu", switch_underlying);
|
||||
|
||||
}}
|
Loading…
Reference in New Issue
Block a user