improved Worm/Tentacle/Snake graphics

This commit is contained in:
Zeno Rogue 2018-01-11 23:18:02 +01:00
parent 02f63201d6
commit 2afe841a50
2 changed files with 109 additions and 12 deletions

104
graph.cpp
View File

@ -1725,9 +1725,10 @@ double chainAngle(cell *c, transmatrix& V, cell *c2, double dft, const transmatr
}
// equivalent to V = V * spin(-chainAngle(c,V,c2,dft));
bool chainAnimation(cell *c, transmatrix& V, cell *c2, int i, int b, const transmatrix &Vwhere) {
bool chainAnimation(cell *c, transmatrix& V, cell *c2, int i, int b, const transmatrix &Vwhere, ld& length) {
if(!gmatrix0.count(c2)) {
V = V * ddspin(c,i,b);
length = cellgfxdist(c,i);
return false;
}
hyperpoint h = C0;
@ -1736,6 +1737,7 @@ bool chainAnimation(cell *c, transmatrix& V, cell *c2, int i, int b, const trans
h = inverse(V) * Vwhere * inverse(gmatrix0[c]) * gmatrix0[c2] * h;
else
h = inverse(V) * gmatrix0[c2] * h;
length = hdist0(h);
V = V * rspintox(h);
return true;
}
@ -1764,6 +1766,31 @@ int cellcolor(cell *c) {
return OUTLINE_NONE;
}
int taildist(cell *c) {
int s = 0;
while(s < 1000 && c->mondir != NODIR && isWorm(c->monst)) {
s++; c = c->mov[c->mondir];
}
return s;
}
int last_wormsegment = -1;
vector<vector< std::function<void()> > > wormsegments;
void add_segment(int d, const std::function<void()>& s) {
if(size(wormsegments) <= d) wormsegments.resize(d+1);
last_wormsegment = max(last_wormsegment, d);
wormsegments[d].push_back(s);
}
void drawWormSegments() {
for(int i=0; i<=last_wormsegment; i++) {
for(auto& f: wormsegments[i]) f();
wormsegments[i].clear();
}
last_wormsegment = -1;
}
bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
bool darkhistory = conformal::includeHistory && eq(c->aitmp, sval);
@ -1803,20 +1830,27 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
if(c->mondir != NODIR) {
if(mmmon) {
if(nospinb)
chainAnimation(c, Vb, c->mov[c->mondir], c->mondir, 0, Vparam);
else
ld length;
// cell *c2 = c->mov[c->mondir];
if(nospinb)
chainAnimation(c, Vb, c->mov[c->mondir], c->mondir, 0, Vparam, length);
else {
Vb = Vb * ddspin(c, c->mondir);
length = cellgfxdist(c, c->mondir);
}
if(mapeditor::drawUserShape(Vb, 1, c->monst, (col << 8) + 0xFF, c)) return false;
if(isIvy(c) || isMutantIvy(c) || c->monst == moFriendlyIvy)
queuepoly(Vb, shIBranch, (col << 8) + 0xFF);
else if(c->monst < moTentacle) {
/* else if(c->monst < moTentacle && wormstyle == 0) {
ShadowV(Vb, shTentacleX, PPR_GIANTSHADOW);
queuepoly(mmscale(Vb, geom3::ABODY), shTentacleX, 0xFF);
queuepoly(mmscale(Vb, geom3::ABODY), shTentacle, (col << 8) + 0xFF);
}
} */
// else if(c->monst < moTentacle) {
// }
else if(c->monst == moDragonHead || c->monst == moDragonTail) {
char part = dragon::bodypart(c, dragon::findhead(c));
if(part != '2') {
@ -1832,9 +1866,32 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
drawMonsterType(moGhost, c, Vs, darkena(col, 0, 0xFF), footphase);
col = minf[moTentacletail].color;
}
/*
queuepoly(mmscale(Vb, geom3::ABODY), shTentacleX, 0xFFFFFFFF);
queuepoly(mmscale(Vb, geom3::ABODY), shTentacle, (col << 8) + 0xFF);
ShadowV(Vb, shTentacleX, PPR_GIANTSHADOW);
*/
bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail;
bool thead = c->monst == moTentacle || c->monst == moTentaclewait || c->monst == moTentacleEscaping;
hpcshape& sh = hexsnake ? shWormSegment : shSmallWormSegment;
ld wav = hexsnake ? 0 :
c->monst < moTentacle ? 1/1.5 :
1;
int col0 = col;
if(c->monst == moWorm || c->monst == moWormwait)
col0 = minf[moWormtail].color;
else if(thead)
col0 = minf[moTentacletail].color;
add_segment(taildist(c), [=] () {
for(int i=11; i>=0; i--) {
if(i < 3 && (c->monst == moTentacle || c->monst == moTentaclewait)) continue;
transmatrix Vbx = Vb * spin(sin(M_PI * i / 6.) * wav / (i+.1)) * xpush(length * (i) / 12.0);
// transmatrix Vbx2 = Vnext * xpush(length2 * i / 6.0);
// Vbx = Vbx * rspintox(inverse(Vbx) * Vbx2 * C0) * pispin;
ShadowV(Vbx, sh, PPR_GIANTSHADOW);
queuepoly(mmscale(Vbx, geom3::ABODY), sh, (col0 << 8) + 0xFF);
}
});
}
}
@ -1883,7 +1940,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
char part = dragon::bodypart(c, dragon::findhead(c));
if(part == 't') {
if(nospinb) {
chainAnimation(c, Vb, c2, nd, 0, Vparam);
ld length;
chainAnimation(c, Vb, c2, nd, 0, Vparam, length);
Vb = Vb * pispin;
}
else {
@ -1895,7 +1953,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
}
else if(true) {
if(nospinb) {
chainAnimation(c, Vb, c2, nd, 0, Vparam);
ld length;
chainAnimation(c, Vb, c2, nd, 0, Vparam, length);
Vb = Vb * pispin;
double ang = chainAngle(c, Vb, c->mov[c->mondir], (displaydir(c, c->mondir) - displaydir(c, nd)) * M_PI / S42, Vparam);
ang /= 2;
@ -1916,8 +1975,29 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
}
}
else {
if(!(c->mondir == NODIR && (c->monst == moTentacletail || (c->monst == moWormtail && wormpos(c) < WORMLENGTH))))
queuepoly(Vb, shJoint, darkena(col, 0, 0xFF));
if(c->monst == moTentacletail && c->mondir == NODIR) {
queuepoly(Vb, shWormSegment, darkena(col, 0, 0xFF));
}
else if(c->mondir == NODIR) {
bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail;
cell *c2 = NULL;
for(int i=0; i<c->type; i++)
if(c->mov[i] && isWorm(c->mov[i]->monst) && c->mov[i]->mondir == c->spn(i))
c2 = c->mov[i];
int nd = neighborId(c, c2);
if(nospinb) {
ld length;
chainAnimation(c, Vb, c2, nd, 0, Vparam, length);
Vb = Vb * pispin;
}
else {
Vb = Vb0 * ddspin(c, nd, S42);
}
transmatrix Vbb = mmscale(Vb, geom3::ABODY) * pispin;
hpcshape& sh = hexsnake ? shWormTail : shSmallWormTail;
queuepoly(Vbb, sh, darkena(col, 0, 0xFF));
ShadowV(Vb, sh, PPR_GIANTSHADOW);
}
}
}
@ -1990,7 +2070,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
else if(c->monst == moKrakenT) {
if(c->hitpoints == 0) col = 0x404040;
if(nospinb) {
chainAnimation(c, Vb, c->mov[c->mondir], c->mondir, 0, Vparam);
ld length;
chainAnimation(c, Vb, c->mov[c->mondir], c->mondir, 0, Vparam, length);
Vb = Vb * pispin;
}
else Vb = Vb * ddspin(c, c->mondir, S42);
@ -5070,6 +5151,7 @@ void drawthemap() {
drawrec(viewctr, maxreclevel, hsOrigin, cview());
}
drawWormSegments();
drawBlizzards();
drawArrowTraps();
ivoryz = false;

View File

@ -1012,7 +1012,7 @@ hpcshape
shSabre, shTurban1, shTurban2, shVikingHelmet, shRaiderHelmet, shRaiderArmor, shRaiderBody, shRaiderShirt,
shWestHat1, shWestHat2, shGunInHand,
shKnightArmor, shKnightCloak, shWightCloak,
shGhost, shEyes, shSlime, shJelly, shJoint, shWormHead, shTentHead, shShark,
shGhost, shEyes, shSlime, shJelly, shJoint, shWormHead, shTentHead, shShark, shWormSegment, shSmallWormSegment, shWormTail, shSmallWormTail,
shHedgehogBlade, shHedgehogBladePlayer,
shWolfBody, shWolfHead, shWolfLegs, shWolfEyes,
shWolfFrontLeg, shWolfRearLeg, shWolfFrontPaw, shWolfRearPaw,
@ -2000,6 +2000,16 @@ void buildpolys() {
copyshape(shJoint, shDisk, PPR_ONTENTACLE);
bshape(shTentHead, PPR_ONTENTACLE, scalef, 79);
bshape(shWormHead, PPR_ONTENTACLE, scalef, 80);
bshape(shWormSegment, PPR_TENTACLE1);
for(int i=0; i<=S84; i+=S3)
hpcpush(ddi(i, .20 * scalef) * C0);
bshape(shSmallWormSegment, PPR_TENTACLE1);
for(int i=0; i<=S84; i+=S3)
hpcpush(ddi(i, .16 * scalef) * C0);
bshape(shWormTail, PPR_TENTACLE1, scalef, 383);
bshape(shSmallWormTail, PPR_TENTACLE1, scalef, 384);
if(nonbitrunc) bshape(shDragonSegment, PPR_TENTACLE1, 1, 233);
else bshape(shDragonSegment, PPR_TENTACLE1, scalef, 234);
bshape(shDragonWings, PPR_ONTENTACLE, scalef, 237);
@ -3451,6 +3461,11 @@ NEWSHAPE, 379, 7, 1, 0.649585,0.084560, 0.623391,0.075842, 0.599921,0.058309, 0.
NEWSHAPE, 380, 1, 2, -0.157063,0.003936, -0.151414,0.044436, -0.065427,0.009052, -0.151414,0.044436, -0.151129,0.067964, -0.072440,0.024229, -0.150301,0.069258, -0.113069,0.110826, -0.037964,0.039249, -0.110463,0.109185, -0.011307,0.146227, -0.108855,0.111771, -0.113069,0.110826, -0.110452,0.155897, -0.007227,0.165082, -0.111749,0.156720, -0.114514,0.196200, 0.003252,0.188966, -0.009486,0.143350, 0.043508,0.083540, 0.057523,0.000604,
NEWSHAPE, 381, 1, 2, -0.128015,0.002500, -0.121343,0.106487, -0.104134,0.121999, -0.063293,0.274181, 0.038783,0.286293, 0.071085,0.292868, 0.087907,0.266956, 0.077475,0.243894, 0.083000,0.234337, 0.068629,0.220991, 0.042226,0.206757, 0.023044,0.227068, -0.009573,0.218873, -0.027348,0.140245, -0.005432,-0.096462, 0.020544,-0.030837,
NEWSHAPE, 382, 1, 2, 0.024784,0.028900, -0.009988,0.111744, -0.018320,0.147991, -0.006519,0.215354, 0.020083,0.223620, 0.029811,0.291799, -0.066579,0.278718, -0.136927,0.082023, -0.147101,-0.050084,
NEWSHAPE, 383, 1, 2, 0.164154,0.032677, 0.112722,0.126268, 0.093106,0.144972, 0.036998,0.184005, -0.028137,0.220088, -0.088953,0.208314, -0.221199,0.117397, -0.270025,0.057450, -0.290973,0.020569,
NEWSHAPE, 384, 1, 2, 0.146470,0.021791, 0.134179,0.071381, 0.089857,0.116839, 0.039860,0.139410, -0.005910,0.150902, -0.047971,0.139775, -0.104973,0.100695, -0.147597,0.052809, -0.177722,0.017653, -0.186756,0.003107,
NEWSHAPE
};