1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-27 14:37:16 +00:00

stuck prevention and wall sliding

This commit is contained in:
Zeno Rogue 2019-10-05 15:37:13 +02:00
parent 82f7ae05d2
commit a023003560

View File

@ -294,6 +294,7 @@ EX void degradeDemons() {
// we need these for the Mimics! // we need these for the Mimics!
EX double playerturn[MAXPLAYER], playergo[MAXPLAYER], playerstrafe[MAXPLAYER], playerturny[MAXPLAYER], playergoturn[MAXPLAYER], godir[MAXPLAYER]; EX double playerturn[MAXPLAYER], playergo[MAXPLAYER], playerstrafe[MAXPLAYER], playerturny[MAXPLAYER], playergoturn[MAXPLAYER], godir[MAXPLAYER];
EX transmatrix playersmallspin[MAXPLAYER];
bool playerfire[MAXPLAYER]; bool playerfire[MAXPLAYER];
void awakenMimics(monster *m, cell *c2) { void awakenMimics(monster *m, cell *c2) {
@ -977,27 +978,40 @@ void movePlayer(monster *m, int delta) {
// if(inertia_based) m->inertia = spin(-playerturn[cpid]) * m->inertia; // if(inertia_based) m->inertia = spin(-playerturn[cpid]) * m->inertia;
} }
bool have_speed = false;
int fspin = 0;
for(int igo=0; igo<IGO && !go; igo++) { for(int igo=0; igo<IGO && !go; igo++) {
go = true; go = true;
playergoturn[cpid] = igospan[igo]+godir[cpid];
if(inertia_based) { if(inertia_based) {
playergoturn[cpid] = 0;
if(igo) { go = false; break; } if(igo) { go = false; break; }
ld r = hypot_d(WDIM, avg_inertia); ld r = hypot_d(WDIM, avg_inertia);
have_speed = r;
apply_parallel_transport(nat, m->ori, rspintox(avg_inertia) * xtangent(r * delta)); apply_parallel_transport(nat, m->ori, rspintox(avg_inertia) * xtangent(r * delta));
if(WDIM == 3) rotate_object(nat, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid])); if(WDIM == 3) rotate_object(nat, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
m->vel = r * (600/SCALE); m->vel = r * (600/SCALE);
} }
else if(WDIM == 3) { else if(WDIM == 3) {
nat = parallel_transport(nat1, m->ori, point3(playerstrafe[cpid], 0, playergo[cpid])); playersmallspin[cpid] = Id;
if(igo) {
fspin += 30;
playersmallspin[cpid] = cspin(0, 1, fspin) * cspin(2, 0, igospan[igo]);
if(fspin < 360) igo--; else fspin = 0;
}
have_speed = playerstrafe[cpid] || playergo[cpid];
nat = parallel_transport(nat1, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
rotate_object(nat, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid])); rotate_object(nat, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
m->inertia[0] = playerstrafe[cpid] / delta; m->inertia[0] = playerstrafe[cpid] / delta;
m->inertia[1] = 0; m->inertia[1] = 0;
m->inertia[2] = playergo[cpid] / delta; m->inertia[2] = playergo[cpid] / delta;
} }
else if(playergo[cpid]) { else if(playergo[cpid]) {
playergoturn[cpid] = igospan[igo]+godir[cpid];
have_speed = true;
nat = parallel_transport(nat1, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid])); nat = parallel_transport(nat1, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid]));
m->inertia = spin(playergoturn[cpid]) * xtangent(playergo[cpid] / delta); m->inertia = spin(playergoturn[cpid]) * xtangent(playergo[cpid] / delta);
} }
@ -1173,6 +1187,22 @@ void movePlayer(monster *m, int delta) {
} }
} }
if(!go && !have_speed) {
/* sometimes, when we move too fast, we may get stuck */
cell *c2 = m->findbase(nat0, 1);
if(c2 != m->base) {
hyperpoint v;
for(int i=0; i<GDIM; i++) v[i] = (randd() - randd()) * 0.01;
nat = nat0;
apply_parallel_transport(nat, m->ori, v);
transmatrix B = ggmatrix(m->base);
horo_distance d0(tC0(nat0), B);
horo_distance d1(tC0(nat), B);
horo_distance d2(tC0(nat0), ggmatrix(c2));
if(d1 < d0) nat0 = nat;
}
}
if(go) m->rebasePat(nat, c2); if(go) m->rebasePat(nat, c2);
else m->rebasePat(nat0, m->base); else m->rebasePat(nat0, m->base);