mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 06:27:17 +00:00
Orb of the Sword in non-shmup 3D geometries
This commit is contained in:
parent
84df837855
commit
3a4e84effe
53
complex.cpp
53
complex.cpp
@ -2620,14 +2620,17 @@ namespace dragon {
|
||||
}
|
||||
|
||||
namespace sword {
|
||||
array<int, MAXPLAYER> angle;
|
||||
|
||||
int sword_angles;
|
||||
|
||||
array<sworddir, MAXPLAYER> dir;
|
||||
|
||||
void possible_divisor(int s) { sword_angles *= s / gcd(sword_angles, s); }
|
||||
|
||||
void determine_sword_angles() {
|
||||
sword_angles = 2;
|
||||
if(IRREGULAR) sword_angles = 840;
|
||||
if(DIM == 3) sword_angles = 1;
|
||||
else if(IRREGULAR) sword_angles = 840;
|
||||
else if(binarytiling) sword_angles = 42;
|
||||
else if(archimedean) {
|
||||
if(!PURE) possible_divisor((BITRUNCATED ? 2 : 1) * isize(arcm::current.faces));
|
||||
@ -2639,7 +2642,7 @@ namespace sword {
|
||||
}
|
||||
}
|
||||
|
||||
cell *pos(cell *c, int s) {
|
||||
cell *pos2(cell *c, int s) {
|
||||
int t = c->type;
|
||||
s *= 2;
|
||||
s += sword_angles/t;
|
||||
@ -2650,12 +2653,26 @@ namespace sword {
|
||||
return c->move(s);
|
||||
}
|
||||
|
||||
cell *pos(cell *c, const sworddir& sd, bool rev) {
|
||||
if(WDIM == 2)
|
||||
return pos2(c, sd.angle + (rev ? sword_angles/2 : 0));
|
||||
else {
|
||||
cell *best = NULL;
|
||||
ld bdist = HUGE_VAL;
|
||||
for(int i=0; i<S7; i++) {
|
||||
ld dist = hdist(sd.T * xpush0(rev?-0.1:0.1), tC0(currentmap->relative_matrix(c->move(i)->master, c->master)));
|
||||
if(dist < bdist) bdist = dist, best = c->move(i);
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
||||
eItem orbof(bool rev) { return rev ? itOrbSword2 : itOrbSword; }
|
||||
int orbcount(bool rev) { return items[orbof(rev)]; }
|
||||
|
||||
cell *pos(int id, bool rev) {
|
||||
if(!orbcount(rev)) return NULL;
|
||||
return pos(playerpos(id), angle[id] + (rev ? sword_angles/2 : 0));
|
||||
return pos(playerpos(id), dir[id], rev);
|
||||
}
|
||||
|
||||
bool at(cell *where, bool noplayer) {
|
||||
@ -2673,19 +2690,29 @@ namespace sword {
|
||||
}
|
||||
|
||||
// from c1 to c2
|
||||
int shift(cell *c1, cell *c2, int angle) {
|
||||
if(!c1 || !c2) return 0;
|
||||
sworddir shift(cell *c1, cell *c2, sworddir d) {
|
||||
if(!c1 || !c2) return d;
|
||||
int s1 = neighborId(c1, c2);
|
||||
int s2 = neighborId(c2, c1);
|
||||
if(s1 < 0 || s2 < 0) return angle;
|
||||
if(c1->c.mirror(s1))
|
||||
return ((s2*sword_angles/c2->type - angle + s1*sword_angles/c1->type) + sword_angles/2) % sword_angles;
|
||||
else
|
||||
return ((s2*sword_angles/c2->type - s1*sword_angles/c1->type) + sword_angles/2 + angle) % sword_angles;
|
||||
if(s1 < 0 || s2 < 0) return d;
|
||||
if(WDIM == 2) {
|
||||
if(c1->c.mirror(s1))
|
||||
d.angle = ((s2*sword_angles/c2->type - d.angle + s1*sword_angles/c1->type) + sword_angles/2) % sword_angles;
|
||||
else
|
||||
d.angle = ((s2*sword_angles/c2->type - s1*sword_angles/c1->type) + sword_angles/2 + d.angle) % sword_angles;
|
||||
}
|
||||
else {
|
||||
transmatrix T = currentmap->relative_matrix(c1->master, c2->master);
|
||||
T = gpushxto0(tC0(T)) * T;
|
||||
d.T = T * d.T;
|
||||
fixmatrix(d.T);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
void shuffle(int i) {
|
||||
sword::angle[i] = euclid ? S7*hrand(6) : PURE ? 3*hrand(sword_angles/3)+1 : hrand(sword_angles);
|
||||
dir[i].angle = hrand(sword_angles);
|
||||
dir[i].T = Id;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
@ -3217,7 +3244,7 @@ auto ccm = addHook(clearmemory, 0, [] () {
|
||||
gd->store(prairie::enter);
|
||||
gd->store(prairie::tchoices);
|
||||
gd->store(prairie::beaststogen);
|
||||
gd->store(sword::angle);
|
||||
gd->store(sword::dir);
|
||||
gd->store(elec::haveelec);
|
||||
gd->store(elec::havecharge);
|
||||
gd->store(elec::lightningfast);
|
||||
|
12
game.cpp
12
game.cpp
@ -1464,9 +1464,9 @@ bool monstersnear(cell *c, cell *nocount, eMonster who, cell *pushto, cell *come
|
||||
|
||||
dynamicval<cell*> x5(*wcw, c);
|
||||
dynamicval<bool> x6(stalemate::nextturn, true);
|
||||
dynamicval<int> x7(sword::angle[multi::cpid],
|
||||
who == moPlayer ? sword::shift(comefrom, c, sword::angle[multi::cpid]) :
|
||||
sword::angle[multi::cpid]);
|
||||
dynamicval<sword::sworddir> x7(sword::dir[multi::cpid],
|
||||
who == moPlayer ? sword::shift(comefrom, c, sword::dir[multi::cpid]) :
|
||||
sword::dir[multi::cpid]);
|
||||
|
||||
for(int b=0; b<2; b++) {
|
||||
if(who == moPlayer) {
|
||||
@ -3545,7 +3545,7 @@ void playerMoveEffects(cell *c1, cell *c2) {
|
||||
|
||||
if(peace::on) items[itOrbSword] = c2->land == laBurial ? 100 : 0;
|
||||
|
||||
sword::angle[multi::cpid] = sword::shift(c1, c2, sword::angle[multi::cpid]);
|
||||
sword::dir[multi::cpid] = sword::shift(c1, c2, sword::dir[multi::cpid]);
|
||||
|
||||
destroyWeakBranch(c1, c2, moPlayer);
|
||||
|
||||
@ -5267,8 +5267,8 @@ void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) {
|
||||
|
||||
template<class T> void do_swords(cell *mf, cell *mt, eMonster who, const T& f) {
|
||||
for(int bb=0; bb<2; bb++) if(who == moPlayer && sword::orbcount(bb)) {
|
||||
cell *sf = sword::pos(mf, sword::angle[multi::cpid] + (bb?sword::sword_angles/2:0));
|
||||
cell *st = sword::pos(mt, sword::shift(mf, mt, sword::angle[multi::cpid]) + (bb?sword::sword_angles/2:0));
|
||||
cell *sf = sword::pos(mf, sword::dir[multi::cpid], bb);
|
||||
cell *st = sword::pos(mt, sword::shift(mf, mt, sword::dir[multi::cpid]), bb);
|
||||
f(st, bb);
|
||||
if(sf != st && !isNeighbor(sf,st)) {
|
||||
// also attack the in-transit cell
|
||||
|
21
graph.cpp
21
graph.cpp
@ -391,18 +391,22 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(shmup::on && WDIM == 3) {
|
||||
else if(WDIM == 3) {
|
||||
#if CAP_SHAPES
|
||||
transmatrix Vsword =
|
||||
shmup::on ? V * shmup::swordmatrix[multi::cpid] * cspin(2, 0, M_PI/2)
|
||||
: gmatrix[c] * rgpushxto0(inverse(gmatrix[c]) * tC0(V)) * sword::dir[multi::cpid].T;
|
||||
|
||||
if(items[itOrbSword])
|
||||
queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200)));
|
||||
queuepoly(Vsword * cspin(1,2, ticks / 150.), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200)));
|
||||
|
||||
if(items[itOrbSword2])
|
||||
queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, -M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0xC0 + 0x30 * sintick(200)));
|
||||
queuepoly(Vsword * pispin * cspin(1,2, ticks / 150.), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0xC0 + 0x30 * sintick(200)));
|
||||
#endif
|
||||
}
|
||||
|
||||
else {
|
||||
int& ang = angle[multi::cpid];
|
||||
int& ang = sword::dir[multi::cpid].angle;
|
||||
ang %= sword::sword_angles;
|
||||
|
||||
#if CAP_QUEUE || CAP_SHAPES
|
||||
@ -415,7 +419,7 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
|
||||
if(!euclid) for(int a=0; a<sword_angles; a++) {
|
||||
if(a == ang && items[itOrbSword]) continue;
|
||||
if((a+sword_angles/2)%sword_angles == ang && items[itOrbSword2]) continue;
|
||||
bool longer = sword::pos(cwt.at, a-1) != sword::pos(cwt.at, a+1);
|
||||
bool longer = sword::pos2(cwt.at, a-1) != sword::pos2(cwt.at, a+1);
|
||||
if(sword_angles > 48 && !longer) continue;
|
||||
color_t col = darkena(0xC0C0C0, 0, 0xFF);
|
||||
ld l0 = PURE ? 0.6 * cgi.scalefactor : longer ? 0.36 : 0.4;
|
||||
@ -6862,6 +6866,13 @@ void drawMarkers() {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(WDIM == 3 && !shmup::on) {
|
||||
if(items[itOrbSword])
|
||||
queuechr(gmatrix[cwt.at] * sword::dir[multi::cpid].T * xpush0(cgi.sword_size), vid.fsize*2, '+', iinf[itOrbSword].color);
|
||||
if(items[itOrbSword2])
|
||||
queuechr(gmatrix[cwt.at] * sword::dir[multi::cpid].T * xpush0(-cgi.sword_size), vid.fsize*2, '+', iinf[itOrbSword2].color);
|
||||
}
|
||||
}
|
||||
|
||||
monsterToSummon = moNone;
|
||||
|
11
hyper.h
11
hyper.h
@ -1862,12 +1862,17 @@ namespace tortoise {
|
||||
|
||||
namespace sword {
|
||||
|
||||
extern array<int, MAXPLAYER> angle;
|
||||
struct sworddir {
|
||||
int angle;
|
||||
transmatrix T;
|
||||
};
|
||||
|
||||
extern array<sworddir, MAXPLAYER> dir;
|
||||
|
||||
cell *pos(cell *c, int s);
|
||||
cell *pos(cell *c, const sworddir& sd, bool rev);
|
||||
cell *pos(int id);
|
||||
bool at(cell *where, bool noplayer = false);
|
||||
int shift(cell *c1, cell *c2);
|
||||
sworddir shift(cell *c1, cell *c2, sworddir);
|
||||
}
|
||||
|
||||
void killThePlayer(eMonster m, int id, flagtype flags);
|
||||
|
@ -210,7 +210,10 @@ void initgame() {
|
||||
}
|
||||
|
||||
sword::determine_sword_angles();
|
||||
for(int i=0; i<numplayers(); i++) sword::angle[i] = (sword::sword_angles / cwt.at->type + 1) / 2;
|
||||
for(int i=0; i<numplayers(); i++) {
|
||||
sword::dir[i].angle = (sword::sword_angles / cwt.at->type + 1) / 2;
|
||||
sword::dir[i].T = Id;
|
||||
}
|
||||
|
||||
#if CAP_DAILY
|
||||
daily::split();
|
||||
|
Loading…
Reference in New Issue
Block a user