1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-10-16 06:37:38 +00:00

MAJOR CHANGE: replaced (transmatrix,band_shift) pair with shiftmatrix

This commit is contained in:
Zeno Rogue
2020-07-27 18:49:04 +02:00
parent d046023164
commit 82f32607e6
47 changed files with 1266 additions and 1129 deletions

207
shmup.cpp
View File

@@ -21,9 +21,9 @@ EX namespace shmupballs {
}
EX }
ld sqdist(hyperpoint a, hyperpoint b) {
ld sqdist(shiftpoint a, shiftpoint b) {
if(prod) return pow(hdist(a, b), 2);
else return intval(a, b);
else return intval(a.h, unshift(b, a.shift));
}
/*
@@ -53,7 +53,7 @@ struct monster {
// tortoises: origin
// butterflies: last position
transmatrix at;
transmatrix pat;
shiftmatrix pat;
/** orientation for the product geometry */
transmatrix ori;
eMonster stk;
@@ -84,9 +84,9 @@ struct monster {
void findpat();
cell *findbase(const transmatrix& T, int maxsteps);
cell *findbase(const shiftmatrix& T, int maxsteps);
void rebasePat(const transmatrix& new_pat, cell *tgt);
void rebasePat(const shiftmatrix& new_pat, cell *tgt);
};
#endif
@@ -112,23 +112,23 @@ typedef multimap<cell*, monster*>::iterator mit;
vector<monster*> active, nonvirtual, additional;
cell *findbaseAround(hyperpoint p, cell *around, int maxsteps) {
cell *findbaseAround(shiftpoint p, cell *around, int maxsteps) {
if(fake::split()) {
auto p0 = inverse(ggmatrix(around)) * p;
auto p0 = inverse_shift(ggmatrix(around), p);
virtualRebase(around, p0);
return around;
}
cell *best = around;
transmatrix T = ggmatrix(around);
shiftmatrix T = ggmatrix(around);
horo_distance d0(p, T);
for(int k=0; k<maxsteps; k++) {
for(int i=0; i<around->type; i++) {
cell *c2 = around->move(i);
if(c2) {
transmatrix U = ggmatrix(c2);
shiftmatrix U = ggmatrix(c2);
horo_distance d1(p, U);
if(d1 < d0) { best = c2; d0 = d1; }
}
@@ -139,7 +139,7 @@ cell *findbaseAround(hyperpoint p, cell *around, int maxsteps) {
return around;
}
cell *findbaseAround(const transmatrix& H, cell *around, int maxsteps) {
cell *findbaseAround(const shiftmatrix& H, cell *around, int maxsteps) {
return findbaseAround(tC0(H), around, maxsteps);
}
@@ -153,15 +153,15 @@ void monster::store() {
}
void monster::findpat() {
isVirtual = !gmatrix.count(base) || invalid_matrix(gmatrix[base]);
isVirtual = !gmatrix.count(base) || invalid_matrix(gmatrix[base].T);
if(!isVirtual) pat = gmatrix[base] * at;
else pat = at;
else pat = shiftless(at);
}
cell *monster::findbase(const transmatrix& T, int maxsteps) {
cell *monster::findbase(const shiftmatrix& T, int maxsteps) {
if(isVirtual) {
cell *c = base;
auto cT = T;
auto cT = T.T;
virtualRebase(c, cT);
return c;
}
@@ -177,18 +177,18 @@ void fix_to_2(transmatrix& T) {
fixelliptic(T);
}
void monster::rebasePat(const transmatrix& new_pat, cell *c2) {
void monster::rebasePat(const shiftmatrix& new_pat, cell *c2) {
if(isVirtual) {
at = new_pat;
at = new_pat.T;
virtualRebase(this);
fix_to_2(at);
pat = at;
pat = shiftless(at);
if(multi::players == 1 && this == shmup::pc[0])
current_display->which_copy = ggmatrix(base);
current_display->which_copy = unshift(ggmatrix(base));
return;
}
if(quotient || fake::split()) {
at = inverse(gmatrix[base]) * new_pat;
at = inverse_shift(gmatrix[base], new_pat);
transmatrix old_at = at;
virtualRebase(this);
fix_to_2(at);
@@ -205,21 +205,21 @@ void monster::rebasePat(const transmatrix& new_pat, cell *c2) {
return;
}
if(multi::players == 1 && this == shmup::pc[0])
current_display->which_copy = current_display->which_copy * inverse(gmatrix[base]) * gmatrix[c2];
current_display->which_copy = current_display->which_copy * inverse_shift(gmatrix[base], gmatrix[c2]);
pat = new_pat;
// if(c2 != base) printf("rebase %p -> %p\n", base, c2);
base = c2;
at = inverse(gmatrix[c2]) * pat;
at = inverse_shift(gmatrix[c2], pat);
fix_to_2(at);
fixelliptic(at);
}
bool trackroute(monster *m, transmatrix goal, double spd) {
bool trackroute(monster *m, shiftmatrix goal, double spd) {
cell *c = m->base;
// queuepoly(goal, shGrail, 0xFFFFFFC0);
transmatrix mat = inverse(m->pat) * goal;
transmatrix mat = inverse_shift(m->pat, goal);
transmatrix mat2 = spintox(mat*C0) * mat;
@@ -227,7 +227,7 @@ bool trackroute(monster *m, transmatrix goal, double spd) {
while(d < dist) {
d += spd;
transmatrix nat = m->pat * rspintox(mat * C0) * xpush(d);
shiftmatrix nat = m->pat * rspintox(mat * C0) * xpush(d);
// queuepoly(nat, cgi.shKnife, 0xFFFFFFC0);
@@ -339,7 +339,7 @@ void awakenMimics(monster *m, cell *c2) {
else
m2->type = moMimic;
hyperpoint H = inverse(gmatrix[c2]) * gmatrix[c] * C0;
hyperpoint H = inverse_shift(gmatrix[c2], tC0(gmatrix[c]));
transmatrix xfer = rgpushxto0(H);
@@ -348,9 +348,9 @@ void awakenMimics(monster *m, cell *c2) {
xfer = rspintox(H) * rpushxto0(H2) * mirrortrans * spintox(H);
}
m2->pat = gmatrix[c2] * xfer * inverse(gmatrix[c2]) * m->pat;
m2->pat = gmatrix[c2] * xfer * inverse_shift(gmatrix[c2], m->pat);
m2->at = inverse(gmatrix[c]) * m2->pat;
m2->at = inverse_shift(gmatrix[c], m2->pat);
m2->pid = cpid;
additional.push_back(m2);
@@ -430,7 +430,7 @@ EX void killThePlayer(eMonster m) {
pc[cpid]->dead = true;
}
monster *playerCrash(monster *who, hyperpoint where) {
monster *playerCrash(monster *who, shiftpoint where) {
if(who->isVirtual) return NULL;
// in the racing mode, neither crashing nor getting too far away is a problem
if(racing::on) return NULL;
@@ -442,7 +442,7 @@ monster *playerCrash(monster *who, hyperpoint where) {
return NULL;
}
void oceanCurrents(transmatrix& nat, monster *m, int delta) {
void oceanCurrents(shiftmatrix& nat, monster *m, int delta) {
cell *c = m->base;
if(c->land == laWhirlpool) {
for(int i=0; i<c->type; i++) {
@@ -457,11 +457,11 @@ void oceanCurrents(transmatrix& nat, monster *m, int delta) {
spd = SCALE * delta / 900.;
if(spd) {
transmatrix goal = gmatrix[c2];
shiftpoint goal = tC0(gmatrix[c2]);
// transmatrix t = spintox(H) * xpush(delta/300.) * rspintox(H);
hyperpoint H = inverse(m->pat) * goal * C0;
hyperpoint H = inverse_shift(m->pat, goal);
nat = nat * rspintox(H);
nat = nat * xpush(spd);
nat = nat * spintox(H);
@@ -470,7 +470,7 @@ void oceanCurrents(transmatrix& nat, monster *m, int delta) {
}
}
bool airCurrents(transmatrix& nat, monster *m, int delta) {
bool airCurrents(shiftmatrix& nat, monster *m, int delta) {
bool carried = false;
cell *c = m->base;
#if CAP_COMPLEX2
@@ -481,11 +481,11 @@ bool airCurrents(transmatrix& nat, monster *m, int delta) {
if(m->type == moVoidBeast) spd = -spd;
if(spd) {
transmatrix goal = gmatrix[c2];
shiftpoint goal = tC0(gmatrix[c2]);
// transmatrix t = spintox(H) * xpush(delta/300.) * rspintox(H);
hyperpoint H = inverse(m->pat) * goal * C0;
hyperpoint H = inverse_shift(m->pat, goal);
nat = nat * rspintox(H);
nat = nat * xpush(spd);
nat = nat * spintox(H);
@@ -503,11 +503,11 @@ bool airCurrents(transmatrix& nat, monster *m, int delta) {
if(m->type == moVoidBeast) spd = -spd;
if(spd) {
transmatrix goal = gmatrix[c2];
shiftpoint goal = tC0(gmatrix[c2]);
// transmatrix t = spintox(H) * xpush(delta/300.) * rspintox(H);
hyperpoint H = inverse(m->pat) * goal * C0;
hyperpoint H = inverse_shift(m->pat, goal);
nat = nat * rspintox(H);
nat = nat * xpush(spd);
nat = nat * spintox(H);
@@ -524,11 +524,11 @@ bool airCurrents(transmatrix& nat, monster *m, int delta) {
if(z >= 128) z -= 256;
if(m->type == moVoidBeast) z = -z;
if(z < windmap::NOWINDFROM && z > -windmap::NOWINDFROM) {
transmatrix goal = gmatrix[c2];
shiftmatrix goal = gmatrix[c2];
// transmatrix t = spintox(H) * xpush(delta/300.) * rspintox(H);
hyperpoint H = inverse(m->pat) * goal * C0;
hyperpoint H = inverse_shift(m->pat, goal) * C0;
nat = nat * rspintox(H);
nat = nat * xpush(z * SCALE * delta / 50000.);
nat = nat * spintox(H);
@@ -540,7 +540,7 @@ bool airCurrents(transmatrix& nat, monster *m, int delta) {
return carried;
}
void roseCurrents(transmatrix& nat, monster *m, int delta) {
void roseCurrents(shiftmatrix& nat, monster *m, int delta) {
if(ignoresSmell(m->type)) return;
cell *c = m->base;
@@ -559,11 +559,11 @@ void roseCurrents(transmatrix& nat, monster *m, int delta) {
double spd = SCALE * delta / 300. / qty;
if(spd) {
transmatrix goal = gmatrix[c2];
shiftpoint goal = tC0(gmatrix[c2]);
// transmatrix t = spintox(H) * xpush(delta/300.) * rspintox(H);
hyperpoint H = inverse(m->pat) * goal * C0;
hyperpoint H = inverse_shift(m->pat, goal);
nat = nat * rspintox(H);
nat = nat * xpush(spd);
nat = nat * spintox(H);
@@ -571,7 +571,7 @@ void roseCurrents(transmatrix& nat, monster *m, int delta) {
}
}
hyperpoint keytarget(int i) {
shiftpoint keytarget(int i) {
double d = 2 + sin(curtime / 350.);
return pc[i]->pat * cpush0(WDIM == 3 ? 2 : 0, d * cgi.scalefactor);
}
@@ -589,14 +589,14 @@ ld getHornsSize() { return cgi.scalefactor * 0.33; }
// used in 3D
EX transmatrix swordmatrix[MAXPLAYER];
hyperpoint swordpos(int id, bool rev, double frac) {
shiftpoint swordpos(int id, bool rev, double frac) {
if(WDIM == 3)
return pc[id]->pat * swordmatrix[id] * cpush0(2, (rev?-frac:frac) * getSwordSize());
else
return pc[id]->pat * xspinpush0(pc[id]->swordangle, (rev?-frac:frac) * getSwordSize());
}
hyperpoint hornpos(int id) {
shiftpoint hornpos(int id) {
return pc[id]->pat * xpush0(getHornsSize());
}
@@ -649,11 +649,11 @@ void doTraps() {
traplist.emplace(t.first + 500, t.second);
for(int i=0; i<5; i += 4) try {
transmatrix& tu = gmatrix.at(tl[i]);
transmatrix& tv = gmatrix.at(tl[4-i]);
shiftmatrix& tu = gmatrix.at(tl[i]);
shiftmatrix& tv = gmatrix.at(tl[4-i]);
monster* bullet = new monster;
bullet->base = tl[i];
bullet->at = rspintox(inverse(tu) * tC0(tv));
bullet->at = rspintox(inverse_shift(tu, tC0(tv)));
bullet->type = moArrowTrap;
bullet->parent = &arrowtrap_fakeparent;
bullet->pid = 0;
@@ -790,7 +790,7 @@ void movePlayer(monster *m, int delta) {
#endif
}
transmatrix nat = m->pat;
shiftmatrix nat = m->pat;
// if(ka == b+pcOrbPower) dropgreen = true;
@@ -827,11 +827,11 @@ void movePlayer(monster *m, int delta) {
if(mdd > 1e-6) {
hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
hyperpoint ctr = m->pat * C0;
shiftpoint ctr = m->pat * C0;
if(sphere && pconf.alpha > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
hyperpoint h = inverse(m->pat) * rgpushxto0(ctr) * jh;
hyperpoint h = inverse_shift(m->pat, rgpushxto0(ctr) * jh);
playerturn[cpid] = -atan2(h[1], h[0]);
mgo += mdd;
@@ -843,7 +843,7 @@ void movePlayer(monster *m, int delta) {
bool forcetarget = (keystate[SDLK_RSHIFT] | keystate[SDLK_LSHIFT]);
if(((mousepressed && !forcetarget) || facemouse) && delta > 0 && !mouseout() && !stdracing && GDIM == 2) {
// playermoved = true;
hyperpoint h = inverse(m->pat) * mouseh;
hyperpoint h = inverse_shift(m->pat, mouseh);
playerturn[cpid] = -atan2(h[1], h[0]);
// nat = nat * spin(alpha);
// mturn += alpha * 150. / delta;
@@ -863,10 +863,10 @@ void movePlayer(monster *m, int delta) {
if(playerturn[cpid] && canmove && !blown && WDIM == 2) {
m->swordangle -= playerturn[cpid];
rotate_object(nat, m->ori, spin(playerturn[cpid]));
rotate_object(nat.T, m->ori, spin(playerturn[cpid]));
if(inertia_based) m->inertia = spin(-playerturn[cpid]) * m->inertia;
}
transmatrix nat0 = nat;
shiftmatrix nat0 = nat;
if(m->base->land == laWhirlpool && !markOrb(itOrbWater))
oceanCurrents(nat, m, delta);
@@ -942,7 +942,7 @@ void movePlayer(monster *m, int delta) {
nextstep:
transmatrix nat1 = nat;
shiftmatrix nat1 = nat;
hyperpoint avg_inertia;
@@ -983,14 +983,13 @@ void movePlayer(monster *m, int delta) {
hyperpoint drag = m->inertia * cinertia * delta / -1. / SCALE;
m->inertia += drag;
avg_inertia += drag/2;
transmatrix T = inverse(m->pat);
ld xp = SCALE / 60000. / isize(below) * delta / 15;
ld yp = 0;
if(cwt.at->land == laDungeon) xp = -xp;
if(cwt.at->land == laWestWall) yp = xp * 1, xp *= 0.7;
for(cell *c2: below) if(c2 != m->base) {
hyperpoint h = rspintox(T * tC0(gmatrix[c2])) * hpxy(xp, yp);
hyperpoint h = rspintox(inverse_shift(m->pat, tC0(gmatrix[c2]))) * hpxy(xp, yp);
m->inertia += h;
avg_inertia += h/2;
@@ -1009,8 +1008,8 @@ void movePlayer(monster *m, int delta) {
playergoturn[cpid] = 0;
if(igo) { go = false; break; }
ld r = hypot_d(WDIM, avg_inertia);
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]));
apply_parallel_transport(nat.T, m->ori, rspintox(avg_inertia) * xtangent(r * delta));
if(WDIM == 3) rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
m->vel = r * (600/SCALE);
}
else if(WDIM == 3) {
@@ -1020,15 +1019,15 @@ void movePlayer(monster *m, int delta) {
playersmallspin[cpid] = cspin(0, 1, fspin) * cspin(2, 0, igospan[igo]);
if(fspin < 360) igo--; else fspin = 0;
}
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]));
nat.T = parallel_transport(nat1.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
m->inertia[0] = playerstrafe[cpid] / delta;
m->inertia[1] = 0;
m->inertia[2] = playergo[cpid] / delta;
}
else if(playergo[cpid]) {
playergoturn[cpid] = igospan[igo]+godir[cpid];
nat = parallel_transport(nat1, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid]));
nat.T = parallel_transport(nat1.T, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid]));
m->inertia = spin(playergoturn[cpid]) * xtangent(playergo[cpid] / delta);
}
@@ -1118,7 +1117,7 @@ void movePlayer(monster *m, int delta) {
int i0 = i;
for(int a=0; a<3; a++) v[a] = (i0 % 3) - 1, i0 /= 3;
v = v * .1 / hypot_d(3, v);
transmatrix T1 = (i == 13) ? nat : parallel_transport(nat, m->ori, v);
shiftmatrix T1 = (i == 13) ? nat : shiftless(parallel_transport(nat.T, m->ori, v), nat.shift);
cell *c3 = c2;
while(true) {
cell *c4 = findbaseAround(tC0(T1), c3, 1);
@@ -1246,7 +1245,7 @@ void movePlayer(monster *m, int delta) {
playerfire[cpid] = false;
if(items[itOrbHorns] && !m->isVirtual) {
hyperpoint H = hornpos(cpid);
shiftpoint H = hornpos(cpid);
for(monster *m2: nonvirtual) {
if(m2 == m) continue;
@@ -1265,7 +1264,7 @@ void movePlayer(monster *m, int delta) {
for(int b=0; b<2; b++) if(sword::orbcount(b) && !m->isVirtual) {
for(double d=0; d<=1.001; d += .1) {
hyperpoint H = swordpos(cpid, b, d);
shiftpoint H = swordpos(cpid, b, d);
for(monster *m2: nonvirtual) {
if(m2 == m) continue;
@@ -1343,23 +1342,23 @@ EX monster *getPlayer() {
void virtualize(monster *m) {
if(doall) forCellCM(c2, m->base) if(!gmatrix.count(c2)) {
m->isVirtual = true;
m->pat = m->at;
m->pat = shiftless(m->at);
return;
}
}
bool reflectmatrix(transmatrix& M, cell *c1, cell *c2, bool onlypos) {
bool reflectmatrix(shiftmatrix& M, cell *c1, cell *c2, bool onlypos) {
if(!gmatrix.count(c1) || !gmatrix.count(c2)) return false;
transmatrix H = inverse(gmatrix[c1]) * gmatrix[c2];
transmatrix H = inverse_shift(gmatrix[c1], gmatrix[c2]);
transmatrix S = spintox(tC0(H));
ld d = hdist0(tC0(H));
transmatrix T = xpush(-d/2) * S * inverse(gmatrix[c1]) * M;
transmatrix T = xpush(-d/2) * S * inverse_shift(gmatrix[c1], M);
if(onlypos && tC0(T)[0] < 0) return false;
M = gmatrix[c1] * inverse(S) * xpush(d/2) * MirrorX * T;
return true;
}
EX int reflect(cell*& c2, cell*& mbase, transmatrix& nat) {
EX int reflect(cell*& c2, cell*& mbase, shiftmatrix& nat) {
int reflections = 0;
if(c2 != mbase && c2->wall == waMirrorWall && inmirror(c2)) {
if(reflectmatrix(nat, mbase, c2, false)) {
@@ -1409,15 +1408,15 @@ EX int reflect(cell*& c2, cell*& mbase, transmatrix& nat) {
void moveMimic(monster *m) {
virtualize(m);
transmatrix nat = m->pat;
shiftmatrix nat = m->pat;
cpid = m->pid;
m->footphase = getPlayer()->footphase;
// no need to care about Mirror images, as they already have their 'at' matrix reversed :|
if(WDIM == 3) {
nat = parallel_transport(nat, 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]));
nat.T = parallel_transport(nat.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
}
else
nat = nat * spin(playerturn[cpid] + playergoturn[cpid]) * xpush(playergo[cpid]) * spin(-playergoturn[cpid]);
@@ -1465,7 +1464,7 @@ void destroyMimics() {
EX void teleported() {
monster *m = pc[cpid];
m->base = cwt.at;
m->at = rgpushxto0(inverse(gmatrix[cwt.at]) * mouseh) * spin(rand() % 1000 * M_PI / 2000);
m->at = rgpushxto0(inverse_shift(gmatrix[cwt.at], mouseh)) * spin(rand() % 1000 * M_PI / 2000);
m->findpat();
destroyMimics();
}
@@ -1473,7 +1472,7 @@ EX void teleported() {
void shoot(eItem it, monster *m) {
monster* bullet = new monster;
bullet->base = m->base;
bullet->at = m->at * rspintox(inverse(m->pat) * mouseh);
bullet->at = m->at * rspintox(inverse_shift(m->pat, mouseh));
/* ori */
if(WDIM == 3) bullet->at = bullet->at * cpush(2, 0.15 * SCALE);
bullet->type = it == itOrbDragon ? moFireball : it == itOrbAir ? moAirball : moBullet;
@@ -1485,7 +1484,7 @@ void shoot(eItem it, monster *m) {
}
eItem targetRangedOrbKey(orbAction a) {
hyperpoint h = mouseh;
shiftpoint h = mouseh;
cell *b = mouseover;
monster *mt = mousetarget;
@@ -1578,7 +1577,7 @@ void spawn_asteroids(monster *bullet, monster *target) {
if(target->hitpoints <= 1) return;
hyperpoint rnd = random_spin() * point2(SCALE/3000., 0);
hyperpoint bullet_inertia = inverse(target->pat) * bullet->pat * bullet->inertia;
hyperpoint bullet_inertia = inverse_shift(target->pat, bullet->pat * bullet->inertia);
for(int i=0; i<2; i++) {
monster* child = new monster;
@@ -1608,8 +1607,8 @@ void moveBullet(monster *m, int delta) {
m->findpat();
virtualize(m);
transmatrix nat0 = m->pat;
transmatrix nat = m->pat;
shiftmatrix nat0 = m->pat;
shiftmatrix nat = m->pat;
bool inertia_based = m->base->land == laAsteroids;
@@ -1633,10 +1632,10 @@ void moveBullet(monster *m, int delta) {
m->dead = true;
if(inertia_based) {
nat = parallel_transport(nat, m->ori, m->inertia * delta);
nat.T = parallel_transport(nat.T, m->ori, m->inertia * delta);
}
else
nat = parallel_transport(nat, m->ori, fronttangent(delta * SCALE * m->vel / speedfactor()));
nat.T = parallel_transport(nat.T, m->ori, fronttangent(delta * SCALE * m->vel / speedfactor()));
cell *c2 = m->findbase(nat, fake::split() ? 10 : 1);
if(m->parent && isPlayer(m->parent) && markOrb(itOrbLava) && c2 != m->base && !isPlayerOn(m->base))
@@ -1717,7 +1716,7 @@ void moveBullet(monster *m, int delta) {
if(m->type == moAirball && isBlowableMonster(m2->type)) {
if(m2->blowoff < curtime) {
hyperpoint h = inverse(m2->pat) * nat0 * C0;
hyperpoint h = inverse_shift(m2->pat, nat0 * C0);
if(WDIM == 3)
swordmatrix[m2->pid] = spintox(h) * swordmatrix[m2->pid];
else
@@ -1729,7 +1728,7 @@ void moveBullet(monster *m, int delta) {
}
// Hedgehog Warriors only killable outside of the 45 degree angle
if(m2->type == moHedge && !peace::on && !slayer) {
hyperpoint h = inverse(m2->pat) * m->pat * C0;
hyperpoint h = inverse_shift(m2->pat, m->pat * C0);
if(h[0] > fabsl(h[1])) { m->dead = true; continue; }
}
if(peace::on && !isIvy(m2->type)) {
@@ -1822,7 +1821,7 @@ void moveBullet(monster *m, int delta) {
}
}
hyperpoint closerTo;
shiftpoint closerTo;
bool closer(monster *m1, monster *m2) {
return sqdist(m1->pat*C0, closerTo) < sqdist(m2->pat*C0, closerTo);
@@ -1832,7 +1831,7 @@ EX bool dragonbreath(cell *dragon) {
int randplayer = hrand(numplayers());
monster* bullet = new monster;
bullet->base = dragon;
bullet->at = spin_towards(Id, bullet->ori, inverse(gmatrix[dragon]) * tC0(pc[randplayer]->pat), bulletdir(), 1);
bullet->at = spin_towards(Id, bullet->ori, inverse_shift(gmatrix[dragon], tC0(pc[randplayer]->pat)), bulletdir(), 1);
bullet->type = moFireball;
bullet->parent = bullet;
bullet->pid = randplayer;
@@ -1882,7 +1881,7 @@ void moveMonster(monster *m, int delta) {
if(m->dead) return;
cell *c = m->base;
transmatrix goal = gmatrix[c];
shiftmatrix goal = gmatrix[c];
bool direct = false; // is there a direct path to the target?
int directi = 0; // which player has direct path (to set as pid in missiles)
@@ -1926,12 +1925,12 @@ void moveMonster(monster *m, int delta) {
if(m->isVirtual) {
if(inertia_based) {
ld r = hypot_d(WDIM, m->inertia);
transmatrix nat = m->pat * rspintox(m->inertia) * xpush(r * delta) * spintox(m->inertia);
shiftmatrix nat = m->pat * rspintox(m->inertia) * xpush(r * delta) * spintox(m->inertia);
m->rebasePat(nat, m->base);
}
return;
}
transmatrix nat = m->pat;
shiftmatrix nat = m->pat;
if(stunned) {
if(m->blowoff > curtime) {
@@ -2062,7 +2061,7 @@ void moveMonster(monster *m, int delta) {
}
if(m->type == moHedge) {
hyperpoint h = inverse(m->pat) * goal * C0;
hyperpoint h = inverse_shift(m->pat, tC0(goal));
if(h[1] < 0)
nat = nat * spin(M_PI * delta / 3000 / speedfactor());
else
@@ -2101,7 +2100,7 @@ void moveMonster(monster *m, int delta) {
int igo = 0;
transmatrix nat0 = nat;
shiftmatrix nat0 = nat;
igo_retry:
@@ -2120,14 +2119,14 @@ void moveMonster(monster *m, int delta) {
if(inertia_based) {
if(igo) return;
nat = parallel_transport(nat, m->ori, m->inertia * delta);
nat.T = parallel_transport(nat.T, m->ori, m->inertia * delta);
}
else if(WDIM == 3 && igo) {
ld fspin = rand() % 1000;
nat = parallel_transport(nat0, m->ori, cspin(1,2,fspin) * spin(igospan[igo]) * xtangent(step));
nat.T = parallel_transport(nat0.T, m->ori, cspin(1,2,fspin) * spin(igospan[igo]) * xtangent(step));
}
else {
nat = parallel_transport(nat0, m->ori, spin(igospan[igo]) * xtangent(step));
nat.T = parallel_transport(nat0.T, m->ori, spin(igospan[igo]) * xtangent(step));
}
if(m->type != moRagingBull && !peace::on)
@@ -2136,7 +2135,7 @@ void moveMonster(monster *m, int delta) {
for(int i=0; i<multi::players; i++) for(int b=0; b<2; b++) if(sword::orbcount(b)) {
if(pc[i]->isVirtual) continue;
hyperpoint H = swordpos(i, b, 1);
shiftpoint H = swordpos(i, b, 1);
double d = sqdist(H, nat*C0);
if(d < SCALE2 * 0.12) { igo++; goto igo_retry; }
}
@@ -2524,7 +2523,7 @@ EX void turn(int delta) {
if(doall)
for(cell *c: currentmap->allcells()) activateMonstersAt(c);
else
for(unordered_map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++)
for(unordered_map<cell*, shiftmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++)
activateMonstersAt(it->first);
/* printf("size: gmatrix = %ld, active = %ld, monstersAt = %ld, delta = %d\n",
@@ -2757,7 +2756,7 @@ EX void init() {
pc[i]->at = Id;
else
pc[i]->at = spin(2*M_PI*i/players) * xpush(firstland == laMotion ? .5 : .3) * Id;
pc[i]->pat = pc[i]->at;
pc[i]->pat = shiftless(pc[i]->at);
pc[i]->base = cwt.at;
pc[i]->vel = 0;
pc[i]->inBoat = (firstland == laCaribbean || firstland == laOcean || firstland == laLivefjord ||
@@ -2785,7 +2784,7 @@ EX bool boatAt(cell *c) {
return false;
}
EX hookset<bool(const transmatrix&, cell*, shmup::monster*)> hooks_draw;
EX hookset<bool(const shiftmatrix&, cell*, shmup::monster*)> hooks_draw;
EX void clearMonsters() {
for(mit it = monstersAt.begin(); it != monstersAt.end(); it++)
@@ -2895,7 +2894,7 @@ bool celldrawer::draw_shmup_monster() {
monstersAt.equal_range(c);
if(p.first == p.second) return false;
ld zlev = -geom3::factor_to_lev(zlevel(tC0(Vd)));
ld zlev = -geom3::factor_to_lev(zlevel(tC0(Vd.T)));
vector<monster*> monsters;
@@ -2903,7 +2902,7 @@ bool celldrawer::draw_shmup_monster() {
monster* m = it->second;
if(c != m->base) continue; // may happen in RogueViz Collatz
m->pat = ggmatrix(m->base) * m->at;
transmatrix view = V * m->at;
shiftmatrix view = V * m->at;
if(!mouseout()) {
if(m->no_targetting) ; else
@@ -2975,7 +2974,7 @@ bool celldrawer::draw_shmup_monster() {
}
if(ths && keyresult[cpid]) {
hyperpoint h = keytarget(cpid);
shiftpoint h = keytarget(cpid);
if(WDIM == 2)
queuestr(h, vid.fsize, "+", iinf[keyresult[cpid]].color);
else {
@@ -2992,7 +2991,7 @@ bool celldrawer::draw_shmup_monster() {
if(m->parenttype == moPlayer)
col = getcs().swordcolor;
else if(m->parenttype == moMimic)
col = (mirrorcolor(det(view) < 0) << 8) | 0xFF;
col = (mirrorcolor(det(view.T) < 0) << 8) | 0xFF;
else
col = (minf[m->parenttype].color << 8) | 0xFF;
if(getcs().charid >= 4) {
@@ -3004,7 +3003,7 @@ bool celldrawer::draw_shmup_monster() {
ShadowV(view, cgi.shPHead);
}
else {
transmatrix t = view * spin(curtime / 50.0);
shiftmatrix t = view * spin(curtime / 50.0);
queuepoly(WDIM == 3 ? t : GDIM == 3 ? mscale(t, cgi.BODY) : mmscale(t, 1.15), cgi.shKnife, col);
ShadowV(t, cgi.shKnife);
}
@@ -3026,14 +3025,14 @@ bool celldrawer::draw_shmup_monster() {
break;
}
case moFlailBullet: case moCrushball: {
transmatrix t = view * spin(curtime / 50.0);
shiftmatrix t = view * spin(curtime / 50.0);
queuepoly(mmscale(t, 1.15), cgi.shFlailMissile, (minf[m->type].color << 8) | 0xFF);
ShadowV(view, cgi.shFlailMissile);
break;
}
case moAsteroid: {
if(GDIM == 3) addradar(view, '*', 0xFFFFFF, 0xC0C0C0FF);
transmatrix t = view;
shiftmatrix t = view;
if(WDIM == 3) t = face_the_player(t);
t = t * spin(curtime / 500.0);
ShadowV(t, cgi.shAsteroid[m->hitpoints & 7]);
@@ -3054,7 +3053,7 @@ bool celldrawer::draw_shmup_monster() {
if(m->inBoat) m->footphase = 0;
color_t col = minf[m->type].color;
if(m->type == moMimic)
col = mirrorcolor(det(view) < 0);
col = mirrorcolor(det(view.T) < 0);
if(m->type == moSlime) {
col = winf[c->wall].color;
col |= (col >> 1);