1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 17:10:36 +00:00

monster orientation is now modelled in non-orientable geometries

This commit is contained in:
Zeno Rogue 2019-05-15 14:19:19 +02:00
parent 5353a82ebf
commit 8c2b717223
5 changed files with 41 additions and 7 deletions

View File

@ -2786,7 +2786,7 @@ namespace kraken {
vector<pair<cell*, cell*> > acells; vector<pair<cell*, cell*> > acells;
acells.push_back(make_pair(c2, c)); acells.push_back(make_pair(c2, c));
forCellIdEx(c3, i, c) { forCellIdEx(c3, i, c) {
c3->monst = moKrakenT, c3->mondir = c->c.spin(i), onpath(c3, 0); c3->monst = moKrakenT, c3->mondir = c->c.spin(i), c3->monmirror = c->monmirror ^ c->c.mirror(i), onpath(c3, 0);
int i0 = (i+c->c.spin(c->mondir)-c->mondir+96+c->type/2) % c2->type; int i0 = (i+c->c.spin(c->mondir)-c->mondir+96+c->type/2) % c2->type;
c3->hitpoints = hpcount[i0]; c3->hitpoints = hpcount[i0];
acells.push_back(make_pair(c2->move(i0), c3)); acells.push_back(make_pair(c2->move(i0), c3));

View File

@ -188,6 +188,7 @@ void initcell(cell *c) {
c->land = laNone; c->land = laNone;
c->ligon = 0; c->ligon = 0;
c->stuntime = 0; c->stuntime = 0;
c->monmirror = 0;
} }
bool doesnotFall(cell *c) { bool doesnotFall(cell *c) {
@ -3664,8 +3665,11 @@ void moveMonster(cell *ct, cell *cf, int direction_hint) {
ct->monst = m; ct->monst = m;
if(m == moWolf) ct->monst = moWolfMoved; if(m == moWolf) ct->monst = moWolfMoved;
if(m == moHunterChanging) ct->stuntime = 1; if(m == moHunterChanging) ct->stuntime = 1;
int d =neighborId(ct, cf);
if(ct->monst != moTentacleGhost) if(ct->monst != moTentacleGhost)
ct->mondir = neighborId(ct, cf); ct->mondir = d;
if(d >= 0)
ct->monmirror = cf->monmirror ^ ct->c.mirror(d);
} }
ct->hitpoints = cf->hitpoints; ct->hitpoints = cf->hitpoints;
ct->stuntime = cf->stuntime; ct->stuntime = cf->stuntime;
@ -4553,6 +4557,7 @@ void moveWorm(cell *c) {
animateMovement(c, goal, LAYER_BIG, dir); animateMovement(c, goal, LAYER_BIG, dir);
c->monst = eMonster(moWormtail + id); c->monst = eMonster(moWormtail + id);
goal->mondir = c->c.spin(j); goal->mondir = c->c.spin(j);
goal->monmirror = c->monmirror ^ c->c.mirror(j);
mountmove(goal, goal->mondir, true, c); mountmove(goal, goal->mondir, true, c);
@ -4589,7 +4594,7 @@ void moveWorm(cell *c) {
} }
void ivynext(cell *c) { void ivynext(cell *c) {
cellwalker cw(c, c->mondir); cellwalker cw(c, c->mondir, c->monmirror);
// check the mirroring status // check the mirroring status
cell *c2 = c; cell *c2 = c;
@ -4683,6 +4688,7 @@ void moveivy() {
if(mto && mto->cpdist) { if(mto && mto->cpdist) {
animateMovement(mto->move(sp), mto, LAYER_BIG, mto->c.spin(sp)); animateMovement(mto->move(sp), mto, LAYER_BIG, mto->c.spin(sp));
mto->monst = moIvyWait, mto->mondir = sp; mto->monst = moIvyWait, mto->mondir = sp;
mto->monmirror = c->monmirror ^ c->c.mirror(sp);
moveEffect(mto, NULL, moIvyWait, NOHINT); moveEffect(mto, NULL, moIvyWait, NOHINT);
// if this is the only branch, we want to move the head immediately to mto instead // if this is the only branch, we want to move the head immediately to mto instead
if(mto->move(mto->mondir)->monst == moIvyHead) { if(mto->move(mto->mondir)->monst == moIvyHead) {

View File

@ -2196,6 +2196,7 @@ bool applyAnimation(cell *c, transmatrix& V, double& footphase, int layer) {
a.footphase += a.attacking == 2 ? -aspd : aspd; a.footphase += a.attacking == 2 ? -aspd : aspd;
footphase = a.footphase; footphase = a.footphase;
V = V * a.wherenow; V = V * a.wherenow;
if(a.mirrored) V = V * Mirror;
if(a.attacking == 2) V = V * pispin; if(a.attacking == 2) V = V * pispin;
// if(DIM == 3) V = V * cspin(0, 2, M_PI/2); // if(DIM == 3) V = V * cspin(0, 2, M_PI/2);
a.ltick = ticks; a.ltick = ticks;
@ -2297,9 +2298,11 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
eMonster m = c->monst; eMonster m = c->monst;
bool half_elliptic = elliptic && GDIM == 3 && WDIM == 2;
if(!m) ; if(!m) ;
else if(elliptic && GDIM == 3 && WDIM == 2 && mirrored) ; else if(half_elliptic && mirrored != c->monmirror && !isMimic(m)) ;
else if(isAnyIvy(c) || isWorm(c)) { else if(isAnyIvy(c) || isWorm(c)) {
@ -2336,6 +2339,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
length = cellgfxdist(c, c->mondir); length = cellgfxdist(c, c->mondir);
} }
if(c->monmirror) Vb = Vb * Mirror;
if(mapeditor::drawUserShape(Vb, mapeditor::sgMonster, c->monst, (col << 8) + 0xFF, c)) if(mapeditor::drawUserShape(Vb, mapeditor::sgMonster, c->monst, (col << 8) + 0xFF, c))
return false; return false;
@ -2411,18 +2416,21 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
queuepoly(Vs, shILeaf[1], darkena(col, 0, 0xFF)); queuepoly(Vs, shILeaf[1], darkena(col, 0, 0xFF));
} }
else { else {
if(c->monmirror) Vb = Vb * Mirror;
queuepoly(mmscale(Vb, geom3::ABODY), shILeaf[ctof(c)], darkena(col, 0, 0xFF)); queuepoly(mmscale(Vb, geom3::ABODY), shILeaf[ctof(c)], darkena(col, 0, 0xFF));
ShadowV(Vb, shILeaf[ctof(c)], PPR::GIANTSHADOW); ShadowV(Vb, shILeaf[ctof(c)], PPR::GIANTSHADOW);
} }
} }
else if(m == moWorm || m == moWormwait || m == moHexSnake) { else if(m == moWorm || m == moWormwait || m == moHexSnake) {
Vb = Vb * pispin; Vb = Vb * pispin;
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbh = mmscale(Vb, geom3::AHEAD); transmatrix Vbh = mmscale(Vb, geom3::AHEAD);
queuepoly(Vbh, shWormHead, darkena(col, 0, 0xFF)); queuepoly(Vbh, shWormHead, darkena(col, 0, 0xFF));
queuepolyat(Vbh, shWormEyes, 0xFF, PPR::ONTENTACLE_EYES); queuepolyat(Vbh, shWormEyes, 0xFF, PPR::ONTENTACLE_EYES);
ShadowV(Vb, shWormHead, PPR::GIANTSHADOW); ShadowV(Vb, shWormHead, PPR::GIANTSHADOW);
} }
else if(m == moDragonHead) { else if(m == moDragonHead) {
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbh = mmscale(Vb, geom3::AHEAD); transmatrix Vbh = mmscale(Vb, geom3::AHEAD);
ShadowV(Vb, shDragonHead, PPR::GIANTSHADOW); ShadowV(Vb, shDragonHead, PPR::GIANTSHADOW);
queuepoly(Vbh, shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF)); queuepoly(Vbh, shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF));
@ -2434,6 +2442,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
} }
else if(m == moTentacle || m == moTentaclewait || m == moTentacleEscaping) { else if(m == moTentacle || m == moTentaclewait || m == moTentacleEscaping) {
Vb = Vb * pispin; Vb = Vb * pispin;
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbh = mmscale(Vb, geom3::AHEAD); transmatrix Vbh = mmscale(Vb, geom3::AHEAD);
queuepoly(Vbh, shTentHead, darkena(col, 0, 0xFF)); queuepoly(Vbh, shTentHead, darkena(col, 0, 0xFF));
ShadowV(Vb, shTentHead, PPR::GIANTSHADOW); ShadowV(Vb, shTentHead, PPR::GIANTSHADOW);
@ -2454,6 +2463,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
else { else {
Vb = Vb0 * ddspin(c, nd, M_PI); Vb = Vb0 * ddspin(c, nd, M_PI);
} }
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbb = mmscale(Vb, geom3::ABODY); transmatrix Vbb = mmscale(Vb, geom3::ABODY);
queuepoly(Vbb, shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF)); queuepoly(Vbb, shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF));
ShadowV(Vb, shDragonTail, PPR::GIANTSHADOW); ShadowV(Vb, shDragonTail, PPR::GIANTSHADOW);
@ -2474,6 +2484,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
while(hdir1 < hdir0 - M_PI) hdir1 += 2*M_PI; while(hdir1 < hdir0 - M_PI) hdir1 += 2*M_PI;
Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI); Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI);
} }
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbb = mmscale(Vb, geom3::ABODY); transmatrix Vbb = mmscale(Vb, geom3::ABODY);
if(part == 'l' || part == '2') { if(part == 'l' || part == '2') {
queuepoly(Vbb, shDragonLegs, darkena(col, c->hitpoints?0:1, 0xFF)); queuepoly(Vbb, shDragonLegs, darkena(col, c->hitpoints?0:1, 0xFF));
@ -2483,6 +2494,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
} }
else { else {
if(c->monst == moTentacletail && c->mondir == NODIR) { if(c->monst == moTentacletail && c->mondir == NODIR) {
if(c->monmirror) Vb = Vb * Mirror;
queuepoly(Vb, shWormSegment, darkena(col, 0, 0xFF)); queuepoly(Vb, shWormSegment, darkena(col, 0, 0xFF));
} }
else if(c->mondir == NODIR) { else if(c->mondir == NODIR) {
@ -2500,6 +2512,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
else { else {
Vb = Vb0 * ddspin(c, nd, M_PI); Vb = Vb0 * ddspin(c, nd, M_PI);
} }
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbb = mmscale(Vb, geom3::ABODY) * pispin; transmatrix Vbb = mmscale(Vb, geom3::ABODY) * pispin;
hpcshape& sh = hexsnake ? shWormTail : shSmallWormTail; hpcshape& sh = hexsnake ? shWormTail : shSmallWormTail;
queuepoly(Vbb, sh, darkena(col, 0, 0xFF)); queuepoly(Vbb, sh, darkena(col, 0, 0xFF));
@ -2527,6 +2540,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
if(d>=4) cw += 2; if(d>=4) cw += 2;
transmatrix Vs = Vparam; transmatrix Vs = Vparam;
bool mirr = cw.mirrored; bool mirr = cw.mirrored;
if(mirrored != mirr && half_elliptic) continue;
transmatrix T = Id; transmatrix T = Id;
nospins = applyAnimation(cwt.at, T, footphase, LAYER_SMALL); nospins = applyAnimation(cwt.at, T, footphase, LAYER_SMALL);
if(nospins) if(nospins)
@ -2555,6 +2569,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
else if(c->monst == moIllusion) { else if(c->monst == moIllusion) {
multi::cpid = 0; multi::cpid = 0;
if(c->monmirror) Vs = Vs * Mirror;
drawMonsterType(c->monst, c, Vs, col, footphase); drawMonsterType(c->monst, c, Vs, col, footphase);
drawPlayerEffects(Vs, c, false); drawPlayerEffects(Vs, c, false);
} }
@ -2571,6 +2586,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
} }
Vs = Vs * ddspin(c, d, 0); Vs = Vs * ddspin(c, d, 0);
} }
if(c->monmirror) Vs = Vs * Mirror;
return drawMonsterTypeDH(m, c, Vs, col, darkhistory, footphase); return drawMonsterTypeDH(m, c, Vs, col, darkhistory, footphase);
} }
@ -2590,6 +2606,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
Vb = Vb * ddspin(c, c->mondir, M_PI); Vb = Vb * ddspin(c, c->mondir, M_PI);
Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir)); Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir));
} }
if(c->monmirror) Vb = Vb * Mirror;
// if(ctof(c) && !masterless) Vb = Vb * xpush(hexhexdist - hcrossf); // if(ctof(c) && !masterless) Vb = Vb * xpush(hexhexdist - hcrossf);
// return (!BITRUNCATED) ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf; // return (!BITRUNCATED) ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
@ -2603,6 +2620,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
if(c->monst == moKrakenH) Vs = Vb, nospins = nospinb; if(c->monst == moKrakenH) Vs = Vb, nospins = nospinb;
if(!nospins && c->mondir < c->type) Vs = Vs * ddspin(c, c->mondir, M_PI); if(!nospins && c->mondir < c->type) Vs = Vs * ddspin(c, c->mondir, M_PI);
if(c->monst == moPair) Vs = Vs * xpush(-.12); if(c->monst == moPair) Vs = Vs * xpush(-.12);
if(c->monmirror) Vs = Vs * Mirror;
if(isFriendly(c)) drawPlayerEffects(Vs, c, false); if(isFriendly(c)) drawPlayerEffects(Vs, c, false);
return drawMonsterTypeDH(m, c, Vs, col, darkhistory, footphase); return drawMonsterTypeDH(m, c, Vs, col, darkhistory, footphase);
} }
@ -2625,6 +2643,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
if(c->monst == moHunterChanging) if(c->monst == moHunterChanging)
Vs = Vs * cspin(WDIM-2, WDIM-1, M_PI); Vs = Vs * cspin(WDIM-2, WDIM-1, M_PI);
} }
if(c->monmirror) Vs = Vs * Mirror;
if(c->monst == moShadow) if(c->monst == moShadow)
multi::cpid = c->hitpoints; multi::cpid = c->hitpoints;
@ -2635,7 +2654,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
for(int i=0; i<numplayers(); i++) if(c == playerpos(i) && !shmup::on && mapeditor::drawplayer && for(int i=0; i<numplayers(); i++) if(c == playerpos(i) && !shmup::on && mapeditor::drawplayer &&
!(hardcore && !canmove)) { !(hardcore && !canmove)) {
bool mirr = multi::players > 1 ? multi::player[i].mirrored : cwt.mirrored; bool mirr = multi::players > 1 ? multi::player[i].mirrored : cwt.mirrored;
if(elliptic && GDIM == 3 && WDIM == 2 && mirr != mirrored) continue; if(half_elliptic && mirr != mirrored) continue;
if(!nospins) { if(!nospins) {
Vs = playerV; Vs = playerV;
if(multi::players > 1 ? multi::flipped[i] : flipplayer) Vs = Vs * pispin; if(multi::players > 1 ? multi::flipped[i] : flipplayer) Vs = Vs * pispin;
@ -7116,6 +7135,11 @@ void animateMovement(cell *src, cell *tgt, int layer, int direction_hint) {
a.ltick = ticks; a.ltick = ticks;
a.wherenow = T; a.wherenow = T;
a.footphase = 0; a.footphase = 0;
a.mirrored = false;
}
if(direction_hint >= 0 && direction_hint < src->type) {
if(src->c.mirror(direction_hint))
a.mirrored = !a.mirrored;
} }
} }

View File

@ -348,7 +348,8 @@ struct gcell {
mondir : 8, // monster direction, for multi-tile monsters and graphics mondir : 8, // monster direction, for multi-tile monsters and graphics
bardir : 8, // barrier direction bardir : 8, // barrier direction
stuntime : 8, // stun time left (for Palace Guards and Skeletons) stuntime : 8, // stun time left (for Palace Guards and Skeletons)
hitpoints : 8; // hitpoints left (for Palace Guards, also reused as cpid for mirrors) hitpoints : 7, // hitpoints left (for Palace Guards, also reused as cpid for mirrors)
monmirror : 1; // monster mirroring state for nonorientable geometries
unsigned landflags : 8; // extra flags for land unsigned landflags : 8; // extra flags for land
#else #else
@ -2082,6 +2083,7 @@ struct animation {
transmatrix wherenow; transmatrix wherenow;
int attacking; int attacking;
transmatrix attackat; transmatrix attackat;
bool mirrored;
}; };
// we need separate animation layers for Orb of Domination and Tentacle+Ghost, // we need separate animation layers for Orb of Domination and Tentacle+Ghost,

View File

@ -13,6 +13,7 @@ int buildIvy(cell *c, int children, int minleaf) {
if(c->monst) return 0; if(c->monst) return 0;
c->mondir = NODIR; c->mondir = NODIR;
c->monst = moIvyRoot; c->monst = moIvyRoot;
c->monmirror = nonorientable && hrand(2);
cell *child = NULL; cell *child = NULL;
@ -25,7 +26,8 @@ int buildIvy(cell *c, int children, int minleaf) {
child = c->move(i), leafchild = buildIvy(c->move(i), children-1, 5); child = c->move(i), leafchild = buildIvy(c->move(i), children-1, 5);
else else
c->move(i)->monst = (leaf++ || peace::on) ? moIvyWait : moIvyHead, c->move(i)->monst = (leaf++ || peace::on) ? moIvyWait : moIvyHead,
c->move(i)->mondir = c->c.spin(i); c->move(i)->mondir = c->c.spin(i),
c->move(i)->monmirror = c->monmirror;
} }
} }