1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 01:00:25 +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;
acells.push_back(make_pair(c2, 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;
c3->hitpoints = hpcount[i0];
acells.push_back(make_pair(c2->move(i0), c3));

View File

@ -188,6 +188,7 @@ void initcell(cell *c) {
c->land = laNone;
c->ligon = 0;
c->stuntime = 0;
c->monmirror = 0;
}
bool doesnotFall(cell *c) {
@ -3664,8 +3665,11 @@ void moveMonster(cell *ct, cell *cf, int direction_hint) {
ct->monst = m;
if(m == moWolf) ct->monst = moWolfMoved;
if(m == moHunterChanging) ct->stuntime = 1;
int d =neighborId(ct, cf);
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->stuntime = cf->stuntime;
@ -4553,6 +4557,7 @@ void moveWorm(cell *c) {
animateMovement(c, goal, LAYER_BIG, dir);
c->monst = eMonster(moWormtail + id);
goal->mondir = c->c.spin(j);
goal->monmirror = c->monmirror ^ c->c.mirror(j);
mountmove(goal, goal->mondir, true, c);
@ -4589,7 +4594,7 @@ void moveWorm(cell *c) {
}
void ivynext(cell *c) {
cellwalker cw(c, c->mondir);
cellwalker cw(c, c->mondir, c->monmirror);
// check the mirroring status
cell *c2 = c;
@ -4683,6 +4688,7 @@ void moveivy() {
if(mto && mto->cpdist) {
animateMovement(mto->move(sp), mto, LAYER_BIG, mto->c.spin(sp));
mto->monst = moIvyWait, mto->mondir = sp;
mto->monmirror = c->monmirror ^ c->c.mirror(sp);
moveEffect(mto, NULL, moIvyWait, NOHINT);
// if this is the only branch, we want to move the head immediately to mto instead
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;
footphase = a.footphase;
V = V * a.wherenow;
if(a.mirrored) V = V * Mirror;
if(a.attacking == 2) V = V * pispin;
// if(DIM == 3) V = V * cspin(0, 2, M_PI/2);
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;
bool half_elliptic = elliptic && GDIM == 3 && WDIM == 2;
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)) {
@ -2336,6 +2339,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
length = cellgfxdist(c, c->mondir);
}
if(c->monmirror) Vb = Vb * Mirror;
if(mapeditor::drawUserShape(Vb, mapeditor::sgMonster, c->monst, (col << 8) + 0xFF, c))
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));
}
else {
if(c->monmirror) Vb = Vb * Mirror;
queuepoly(mmscale(Vb, geom3::ABODY), shILeaf[ctof(c)], darkena(col, 0, 0xFF));
ShadowV(Vb, shILeaf[ctof(c)], PPR::GIANTSHADOW);
}
}
else if(m == moWorm || m == moWormwait || m == moHexSnake) {
Vb = Vb * pispin;
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbh = mmscale(Vb, geom3::AHEAD);
queuepoly(Vbh, shWormHead, darkena(col, 0, 0xFF));
queuepolyat(Vbh, shWormEyes, 0xFF, PPR::ONTENTACLE_EYES);
ShadowV(Vb, shWormHead, PPR::GIANTSHADOW);
}
else if(m == moDragonHead) {
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbh = mmscale(Vb, geom3::AHEAD);
ShadowV(Vb, shDragonHead, PPR::GIANTSHADOW);
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) {
Vb = Vb * pispin;
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbh = mmscale(Vb, geom3::AHEAD);
queuepoly(Vbh, shTentHead, darkena(col, 0, 0xFF));
ShadowV(Vb, shTentHead, PPR::GIANTSHADOW);
@ -2454,6 +2463,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
else {
Vb = Vb0 * ddspin(c, nd, M_PI);
}
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbb = mmscale(Vb, geom3::ABODY);
queuepoly(Vbb, shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF));
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;
Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI);
}
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbb = mmscale(Vb, geom3::ABODY);
if(part == 'l' || part == '2') {
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 {
if(c->monst == moTentacletail && c->mondir == NODIR) {
if(c->monmirror) Vb = Vb * Mirror;
queuepoly(Vb, shWormSegment, darkena(col, 0, 0xFF));
}
else if(c->mondir == NODIR) {
@ -2500,6 +2512,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m
else {
Vb = Vb0 * ddspin(c, nd, M_PI);
}
if(c->monmirror) Vb = Vb * Mirror;
transmatrix Vbb = mmscale(Vb, geom3::ABODY) * pispin;
hpcshape& sh = hexsnake ? shWormTail : shSmallWormTail;
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;
transmatrix Vs = Vparam;
bool mirr = cw.mirrored;
if(mirrored != mirr && half_elliptic) continue;
transmatrix T = Id;
nospins = applyAnimation(cwt.at, T, footphase, LAYER_SMALL);
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) {
multi::cpid = 0;
if(c->monmirror) Vs = Vs * Mirror;
drawMonsterType(c->monst, c, Vs, col, footphase);
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);
}
if(c->monmirror) Vs = Vs * Mirror;
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 * xpush(tentacle_length - cellgfxdist(c, c->mondir));
}
if(c->monmirror) Vb = Vb * Mirror;
// if(ctof(c) && !masterless) Vb = Vb * xpush(hexhexdist - hcrossf);
// 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(!nospins && c->mondir < c->type) Vs = Vs * ddspin(c, c->mondir, M_PI);
if(c->monst == moPair) Vs = Vs * xpush(-.12);
if(c->monmirror) Vs = Vs * Mirror;
if(isFriendly(c)) drawPlayerEffects(Vs, c, false);
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)
Vs = Vs * cspin(WDIM-2, WDIM-1, M_PI);
}
if(c->monmirror) Vs = Vs * Mirror;
if(c->monst == moShadow)
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 &&
!(hardcore && !canmove)) {
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) {
Vs = playerV;
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.wherenow = T;
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
bardir : 8, // barrier direction
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
#else
@ -2082,6 +2083,7 @@ struct animation {
transmatrix wherenow;
int attacking;
transmatrix attackat;
bool mirrored;
};
// 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;
c->mondir = NODIR;
c->monst = moIvyRoot;
c->monmirror = nonorientable && hrand(2);
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);
else
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;
}
}