mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 09:30:35 +00:00
Merge branch 'master' into makefile-fixes
This commit is contained in:
commit
b6f47dd907
@ -6,12 +6,12 @@ namespace hr {
|
|||||||
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
|
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
|
||||||
|
|
||||||
double cellgfxdist(cell *c, int i) {
|
double cellgfxdist(cell *c, int i) {
|
||||||
if(gp::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c)));
|
if(gp::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i)));
|
||||||
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
|
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
|
||||||
}
|
}
|
||||||
|
|
||||||
transmatrix cellrelmatrix(cell *c, int i) {
|
transmatrix cellrelmatrix(cell *c, int i) {
|
||||||
if(gp::on) return shmup::calc_relative_matrix(c->mov[i], c);
|
if(gp::on) return shmup::calc_relative_matrix(c->mov[i], c, i);
|
||||||
double d = cellgfxdist(c, i);
|
double d = cellgfxdist(c, i);
|
||||||
return ddspin(c, i) * xpush(d) * iddspin(c->mov[i], c->spin(i), euclid ? 0 : S42);
|
return ddspin(c, i) * xpush(d) * iddspin(c->mov[i], c->spin(i), euclid ? 0 : S42);
|
||||||
}
|
}
|
||||||
|
9
cell.cpp
9
cell.cpp
@ -1362,16 +1362,17 @@ map<pair<cell*, cell*>, int> saved_distances;
|
|||||||
int celldistance(cell *c1, cell *c2) {
|
int celldistance(cell *c1, cell *c2) {
|
||||||
int d = 0;
|
int d = 0;
|
||||||
|
|
||||||
if(euclid) {
|
if(euclid6) {
|
||||||
if(torus)
|
if(!torus)
|
||||||
|
return eudist(decodeId(c1->master) - decodeId(c2->master));
|
||||||
|
else if(torus && torusconfig::torus_mode == 0)
|
||||||
return torusmap()->dists[torusconfig::vec_to_id(decodeId(c1->master)-decodeId(c2->master))];
|
return torusmap()->dists[torusconfig::vec_to_id(decodeId(c1->master)-decodeId(c2->master))];
|
||||||
return eudist(decodeId(c1->master) - decodeId(c2->master));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(quotient == 2 && !gp::on)
|
if(quotient == 2 && !gp::on)
|
||||||
return currfp.getdist(fieldpattern::fieldval(c1), fieldpattern::fieldval(c2));
|
return currfp.getdist(fieldpattern::fieldval(c1), fieldpattern::fieldval(c2));
|
||||||
|
|
||||||
if(sphere || quotient) {
|
if(sphere || quotient || torus) {
|
||||||
|
|
||||||
if(saved_distances.count(make_pair(c1,c2)))
|
if(saved_distances.count(make_pair(c1,c2)))
|
||||||
return saved_distances[make_pair(c1,c2)];
|
return saved_distances[make_pair(c1,c2)];
|
||||||
|
@ -2489,3 +2489,8 @@ non-game:
|
|||||||
- uniformized the 'back' and 'help' options in menu (consistent hotkeys, consistent placement, added them where they were missing)
|
- uniformized the 'back' and 'help' options in menu (consistent hotkeys, consistent placement, added them where they were missing)
|
||||||
- pushing a thumper through a stranded boat is no longer allowed
|
- pushing a thumper through a stranded boat is no longer allowed
|
||||||
- fixed a bug with pushing Thumpers through tentacles
|
- fixed a bug with pushing Thumpers through tentacles
|
||||||
|
|
||||||
|
2018.06.14 16:39
|
||||||
|
- fixed viewing the "past challenges"
|
||||||
|
- fixed a bug which sometimes caused current scores to be copied to past challenge leaderboards.
|
||||||
|
|
||||||
|
16
complex.cpp
16
complex.cpp
@ -136,7 +136,7 @@ namespace whirlwind {
|
|||||||
for(int i=0; i<z-1; i++) {
|
for(int i=0; i<z-1; i++) {
|
||||||
moveItem(whirlline[i], whirlline[i+1], true);
|
moveItem(whirlline[i], whirlline[i+1], true);
|
||||||
if(whirlline[i]->item)
|
if(whirlline[i]->item)
|
||||||
animateMovement(whirlline[i+1], whirlline[i], LAYER_BOAT);
|
animateMovement(whirlline[i+1], whirlline[i], LAYER_BOAT, NOHINT);
|
||||||
}
|
}
|
||||||
for(int i=0; i<z; i++)
|
for(int i=0; i<z; i++)
|
||||||
pickupMovedItems(whirlline[i]);
|
pickupMovedItems(whirlline[i]);
|
||||||
@ -995,7 +995,7 @@ namespace whirlpool {
|
|||||||
if(wfrom && wto && wfrom->wall == waBoat && wto->wall == waSea && !wto->monst) {
|
if(wfrom && wto && wfrom->wall == waBoat && wto->wall == waSea && !wto->monst) {
|
||||||
wfrom->wall = waSea; wto->wall = waBoat;
|
wfrom->wall = waSea; wto->wall = waBoat;
|
||||||
wto->mondir = neighborId(wto, wfrom);
|
wto->mondir = neighborId(wto, wfrom);
|
||||||
animateMovement(wfrom, wto, LAYER_BOAT);
|
animateMovement(wfrom, wto, LAYER_BOAT, NOHINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wfrom && wto && wfrom->item && !wto->item && wfrom->wall != waBoat) {
|
if(wfrom && wto && wfrom->item && !wto->item && wfrom->wall != waBoat) {
|
||||||
@ -1206,7 +1206,7 @@ namespace mirror {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
c->monst = moMimic;
|
c->monst = moMimic;
|
||||||
moveMonster(c2, c);
|
moveMonster(c2, c, m.second.spin);
|
||||||
c2->monst = moNone;
|
c2->monst = moNone;
|
||||||
empathyMove(c, c2, neighborId(c2, c));
|
empathyMove(c, c2, neighborId(c2, c));
|
||||||
m.second = cw2;
|
m.second = cw2;
|
||||||
@ -1639,7 +1639,7 @@ namespace hive {
|
|||||||
// c->monst = moDeadBug, deadbug.push_back(c);
|
// c->monst = moDeadBug, deadbug.push_back(c);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
moveMonster(c2, c);
|
moveMonster(c2, c, d);
|
||||||
// pheromones!
|
// pheromones!
|
||||||
if(c->land == laHive && c->landparam < 90) c->landparam += 5;
|
if(c->land == laHive && c->landparam < 90) c->landparam += 5;
|
||||||
if(c2->land == laHive && c2->landparam < 90) c2->landparam += 5;
|
if(c2->land == laHive && c2->landparam < 90) c2->landparam += 5;
|
||||||
@ -2297,7 +2297,7 @@ namespace dragon {
|
|||||||
mountmove(c, c->mondir, true, c2);
|
mountmove(c, c->mondir, true, c2);
|
||||||
c->monst = c2->monst;
|
c->monst = c2->monst;
|
||||||
c->hitpoints = c2->hitpoints;
|
c->hitpoints = c2->hitpoints;
|
||||||
animateMovement(c2, c, LAYER_BIG);
|
animateMovement(c2, c, LAYER_BIG, c->spin(c->mondir));
|
||||||
c->stuntime = 2;
|
c->stuntime = 2;
|
||||||
if(c2->mondir == NODIR) { c->mondir = NODIR; c2->monst = moNone; return; }
|
if(c2->mondir == NODIR) { c->mondir = NODIR; c2->monst = moNone; return; }
|
||||||
c = c2;
|
c = c2;
|
||||||
@ -2417,7 +2417,7 @@ namespace dragon {
|
|||||||
cmt->monst = cft->monst;
|
cmt->monst = cft->monst;
|
||||||
cft->monst = moNone;
|
cft->monst = moNone;
|
||||||
mountmove(cmt, cmt->mondir, true, cft);
|
mountmove(cmt, cmt->mondir, true, cft);
|
||||||
animateMovement(cft, cmt, LAYER_BIG);
|
animateMovement(cft, cmt, LAYER_BIG, allcells[i]->mondir);
|
||||||
}
|
}
|
||||||
while(c->mondir != NODIR) {
|
while(c->mondir != NODIR) {
|
||||||
c = c->mov[c->mondir];
|
c = c->mov[c->mondir];
|
||||||
@ -2656,7 +2656,7 @@ namespace kraken {
|
|||||||
noconflict = false; */
|
noconflict = false; */
|
||||||
/* if(noconflict) */ {
|
/* if(noconflict) */ {
|
||||||
// found = true;
|
// found = true;
|
||||||
indAnimateMovement(acells[i].first, acells[i].second, LAYER_BIG);
|
indAnimateMovement(acells[i].first, acells[i].second, LAYER_BIG, NOHINT);
|
||||||
acells[i] = acells[size(acells)-1];
|
acells[i] = acells[size(acells)-1];
|
||||||
acells.resize(size(acells)-1);
|
acells.resize(size(acells)-1);
|
||||||
i--;
|
i--;
|
||||||
@ -2872,7 +2872,7 @@ namespace prairie {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!cn->monst && !isPlayerOn(cn) && passable_for(cp->monst, cn, cp, P_DEADLY))
|
if(!cn->monst && !isPlayerOn(cn) && passable_for(cp->monst, cn, cp, P_DEADLY))
|
||||||
moveMonster(cn, cp);
|
moveMonster(cn, cp, NODIR);
|
||||||
else {
|
else {
|
||||||
playSound(NULL, "hit-axe"+pick123());
|
playSound(NULL, "hit-axe"+pick123());
|
||||||
beastcrash(cn, cp);
|
beastcrash(cn, cp);
|
||||||
|
@ -337,10 +337,10 @@ namespace conformal {
|
|||||||
|
|
||||||
// virtualRebase(v[j], false);
|
// virtualRebase(v[j], false);
|
||||||
|
|
||||||
hyperpoint prev = shmup::calc_relative_matrix(v[j-1]->base, v[j]->base) *
|
hyperpoint prev = shmup::calc_relative_matrix(v[j-1]->base, v[j]->base, NOHINT) *
|
||||||
v[j-1]->at * C0;
|
v[j-1]->at * C0;
|
||||||
|
|
||||||
hyperpoint next = shmup::calc_relative_matrix(v[j+1]->base, v[j]->base) *
|
hyperpoint next = shmup::calc_relative_matrix(v[j+1]->base, v[j]->base, NOHINT) *
|
||||||
v[j+1]->at * C0;
|
v[j+1]->at * C0;
|
||||||
|
|
||||||
hyperpoint hmid = mid(prev, next);
|
hyperpoint hmid = mid(prev, next);
|
||||||
@ -352,7 +352,7 @@ namespace conformal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hyperpoint next0 = shmup::calc_relative_matrix(v[1]->base, v[0]->base) * v[1]->at * C0;
|
hyperpoint next0 = shmup::calc_relative_matrix(v[1]->base, v[0]->base, NOHINT) * v[1]->at * C0;
|
||||||
v[0]->at = v[0]->at * rspintox(inverse(v[0]->at) * next0);
|
v[0]->at = v[0]->at * rspintox(inverse(v[0]->at) * next0);
|
||||||
|
|
||||||
llv = ticks;
|
llv = ticks;
|
||||||
@ -380,7 +380,7 @@ namespace conformal {
|
|||||||
|
|
||||||
hyperpoint now = v[ph]->at * C0;
|
hyperpoint now = v[ph]->at * C0;
|
||||||
|
|
||||||
hyperpoint next = shmup::calc_relative_matrix(v[ph+1]->base, v[ph]->base) *
|
hyperpoint next = shmup::calc_relative_matrix(v[ph+1]->base, v[ph]->base, NOHINT) *
|
||||||
v[ph+1]->at * C0;
|
v[ph+1]->at * C0;
|
||||||
|
|
||||||
View = spin(M_PI/180 * rotation) * xpush(-(phase-ph) * hdist(now, next)) * View;
|
View = spin(M_PI/180 * rotation) * xpush(-(phase-ph) * hdist(now, next)) * View;
|
||||||
@ -411,7 +411,7 @@ namespace conformal {
|
|||||||
for(int j=0; j<siz-1; j++) {
|
for(int j=0; j<siz-1; j++) {
|
||||||
hyperpoint next =
|
hyperpoint next =
|
||||||
inverse(v[j]->at) *
|
inverse(v[j]->at) *
|
||||||
shmup::calc_relative_matrix(v[j+1]->base, v[j]->base) *
|
shmup::calc_relative_matrix(v[j+1]->base, v[j]->base, NOHINT) *
|
||||||
v[j+1]->at * C0;
|
v[j+1]->at * C0;
|
||||||
|
|
||||||
hyperpoint nextscr;
|
hyperpoint nextscr;
|
||||||
|
@ -110,7 +110,7 @@ void calcMousedest() {
|
|||||||
ld dists[MAX_EDGE];
|
ld dists[MAX_EDGE];
|
||||||
|
|
||||||
for(int i=0; i<cwt.c->type; i++)
|
for(int i=0; i<cwt.c->type; i++)
|
||||||
dists[i] = intval(mouseh, tC0(shmup::ggmatrix(cwt.c->mov[i])));
|
dists[i] = intval(mouseh, tC0(confusingGeometry() ? shmup::ggmatrix(cwt.c) * shmup::calc_relative_matrix(cwt.c->mov[i], cwt.c, i) : shmup::ggmatrix(cwt.c->mov[i])));
|
||||||
|
|
||||||
/* printf("curcell = %Lf\n", mousedist);
|
/* printf("curcell = %Lf\n", mousedist);
|
||||||
for(int i=0; i<cwt.c->type; i++)
|
for(int i=0; i<cwt.c->type; i++)
|
||||||
|
@ -303,7 +303,7 @@ namespace gp {
|
|||||||
hyperpoint nearcorner(cell *c, local_info& li, int i) {
|
hyperpoint nearcorner(cell *c, local_info& li, int i) {
|
||||||
cellwalker cw(c, i);
|
cellwalker cw(c, i);
|
||||||
cw += wstep;
|
cw += wstep;
|
||||||
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c);
|
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c, i);
|
||||||
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
|
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
|
||||||
return cwm * C0;
|
return cwm * C0;
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ namespace gp {
|
|||||||
hyperpoint hypercorner(cell *c, local_info& li, int i) {
|
hyperpoint hypercorner(cell *c, local_info& li, int i) {
|
||||||
cellwalker cw(c, i);
|
cellwalker cw(c, i);
|
||||||
cw += wstep;
|
cw += wstep;
|
||||||
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c);
|
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c, i);
|
||||||
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
|
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
|
||||||
auto li1 = get_local_info(cw.c);
|
auto li1 = get_local_info(cw.c);
|
||||||
return cwm * get_corner_position(li1, (cw+2).spin);
|
return cwm * get_corner_position(li1, (cw+2).spin);
|
||||||
@ -358,8 +358,9 @@ namespace gp {
|
|||||||
|
|
||||||
cellwalker cw(c0, c);
|
cellwalker cw(c0, c);
|
||||||
cw += d+sidir+siid+1;
|
cw += d+sidir+siid+1;
|
||||||
|
int hint = cw.spin;
|
||||||
cw += wstep;
|
cw += wstep;
|
||||||
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c0);
|
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c0, hint);
|
||||||
hyperpoint nfar = cwm*C0;
|
hyperpoint nfar = cwm*C0;
|
||||||
auto li1 = get_local_info(cw.c);
|
auto li1 = get_local_info(cw.c);
|
||||||
hyperpoint nlfar = cwm * get_corner_position(li1, (cw+2).spin);
|
hyperpoint nlfar = cwm * get_corner_position(li1, (cw+2).spin);
|
||||||
|
119
game.cpp
119
game.cpp
@ -734,18 +734,18 @@ bool canPushStatueOn(cell *c) {
|
|||||||
!isWorm(c->monst) && !isReptile(c->wall) && !peace::on;
|
!isWorm(c->monst) && !isReptile(c->wall) && !peace::on;
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveBoat(cell *to, cell *from) {
|
void moveBoat(cell *to, cell *from, int direction_hint) {
|
||||||
eWall x = to->wall; to->wall = from->wall; from->wall = x;
|
eWall x = to->wall; to->wall = from->wall; from->wall = x;
|
||||||
to->mondir = neighborId(to, from);
|
to->mondir = neighborId(to, from);
|
||||||
moveItem(from, to, false);
|
moveItem(from, to, false);
|
||||||
animateMovement(from, to, LAYER_BOAT);
|
animateMovement(from, to, LAYER_BOAT, direction_hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveBoatIfUsingOne(cell *to, cell *from) {
|
void moveBoatIfUsingOne(cell *to, cell *from, int direction_hint) {
|
||||||
if(from->wall == waBoat && isWatery(to)) moveBoat(to, from);
|
if(from->wall == waBoat && isWatery(to)) moveBoat(to, from, direction_hint);
|
||||||
else if(from->wall == waBoat && boatGoesThrough(to) && markEmpathy(itOrbWater)) {
|
else if(from->wall == waBoat && boatGoesThrough(to) && markEmpathy(itOrbWater)) {
|
||||||
placeWater(to, from);
|
placeWater(to, from);
|
||||||
moveBoat(to, from);
|
moveBoat(to, from, direction_hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1881,7 +1881,7 @@ bool attackJustStuns(cell *c2, flagtype f) {
|
|||||||
return isStunnable(c2->monst) && c2->hitpoints > 1;
|
return isStunnable(c2->monst) && c2->hitpoints > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveEffect(cell *ct, cell *cf, eMonster m);
|
void moveEffect(cell *ct, cell *cf, eMonster m, int direction_hint);
|
||||||
|
|
||||||
void flameHalfvine(cell *c, int val) {
|
void flameHalfvine(cell *c, int val) {
|
||||||
if(itemBurns(c->item)) {
|
if(itemBurns(c->item)) {
|
||||||
@ -2087,7 +2087,7 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
|
|||||||
}
|
}
|
||||||
if(m == moVineBeast)
|
if(m == moVineBeast)
|
||||||
petrify(c, waVinePlant, m), pcount = 0;
|
petrify(c, waVinePlant, m), pcount = 0;
|
||||||
if(isBird(m)) moveEffect(c, c, moDeadBird);
|
if(isBird(m)) moveEffect(c, c, moDeadBird, -1);
|
||||||
if(m == moBomberbird || m == moTameBomberbird) {
|
if(m == moBomberbird || m == moTameBomberbird) {
|
||||||
pcount = 0;
|
pcount = 0;
|
||||||
playSound(c, "die-bomberbird");
|
playSound(c, "die-bomberbird");
|
||||||
@ -2446,8 +2446,8 @@ bool attackMonster(cell *c, flagtype flags, eMonster killer) {
|
|||||||
return ntk > tk;
|
return ntk > tk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushMonster(cell *ct, cell *cf) {
|
void pushMonster(cell *ct, cell *cf, int direction_hint) {
|
||||||
moveMonster(ct, cf);
|
moveMonster(ct, cf, direction_hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool destroyHalfvine(cell *c, eWall newwall, int tval) {
|
bool destroyHalfvine(cell *c, eWall newwall, int tval) {
|
||||||
@ -3242,7 +3242,7 @@ void activateArrowTrap(cell *c) {
|
|||||||
// this is called from moveMonster, or separately from moveIvy/moveWorm,
|
// this is called from moveMonster, or separately from moveIvy/moveWorm,
|
||||||
// or when a dead bird falls (then m == moDeadBird)
|
// or when a dead bird falls (then m == moDeadBird)
|
||||||
|
|
||||||
void moveEffect(cell *ct, cell *cf, eMonster m) {
|
void moveEffect(cell *ct, cell *cf, eMonster m, int direction_hint) {
|
||||||
|
|
||||||
if(cf) destroyWeakBranch(cf, ct, m);
|
if(cf) destroyWeakBranch(cf, ct, m);
|
||||||
|
|
||||||
@ -3273,7 +3273,7 @@ void moveEffect(cell *ct, cell *cf, eMonster m) {
|
|||||||
if(cf && ct->item == itBabyTortoise && !cf->item) {
|
if(cf && ct->item == itBabyTortoise && !cf->item) {
|
||||||
cf->item = itBabyTortoise;
|
cf->item = itBabyTortoise;
|
||||||
ct->item = itNone;
|
ct->item = itNone;
|
||||||
animateMovement(ct, cf, LAYER_BOAT);
|
animateMovement(ct, cf, LAYER_BOAT, direction_hint);
|
||||||
tortoise::babymap[cf] = tortoise::babymap[ct];
|
tortoise::babymap[cf] = tortoise::babymap[ct];
|
||||||
tortoise::babymap.erase(ct);
|
tortoise::babymap.erase(ct);
|
||||||
}
|
}
|
||||||
@ -3407,20 +3407,20 @@ void makeTrollFootprints(cell *c) {
|
|||||||
c->landparam = turncount + 100;
|
c->landparam = turncount + 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveMonster(cell *ct, cell *cf) {
|
void moveMonster(cell *ct, cell *cf, int direction_hint) {
|
||||||
eMonster m = cf->monst;
|
eMonster m = cf->monst;
|
||||||
bool fri = isFriendly(cf);
|
bool fri = isFriendly(cf);
|
||||||
if(isDragon(m)) {
|
if(isDragon(m)) {
|
||||||
printf("called for Dragon\n");
|
printf("called for Dragon\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(m != moMimic) animateMovement(cf, ct, LAYER_SMALL);
|
if(m != moMimic) animateMovement(cf, ct, LAYER_SMALL, direction_hint);
|
||||||
// the following line is necessary because otherwise plates disappear only inside the sight range
|
// the following line is necessary because otherwise plates disappear only inside the sight range
|
||||||
if(cellUnstable(cf) && !ignoresPlates(m)) {
|
if(cellUnstable(cf) && !ignoresPlates(m)) {
|
||||||
fallingFloorAnimation(cf);
|
fallingFloorAnimation(cf);
|
||||||
cf->wall = waChasm;
|
cf->wall = waChasm;
|
||||||
}
|
}
|
||||||
moveEffect(ct, cf, m);
|
moveEffect(ct, cf, m, direction_hint);
|
||||||
if(ct->wall == waCamelotMoat &&
|
if(ct->wall == waCamelotMoat &&
|
||||||
(m == moShark || m == moCShark || m == moGreaterShark))
|
(m == moShark || m == moCShark || m == moGreaterShark))
|
||||||
achievement_gain("MOATSHARK");
|
achievement_gain("MOATSHARK");
|
||||||
@ -3460,10 +3460,10 @@ void moveMonster(cell *ct, cell *cf) {
|
|||||||
if(ct->wall == waBigStatue) {
|
if(ct->wall == waBigStatue) {
|
||||||
ct->wall = cf->wall;
|
ct->wall = cf->wall;
|
||||||
cf->wall = waBigStatue;
|
cf->wall = waBigStatue;
|
||||||
animateMovement(ct, cf, LAYER_BOAT);
|
animateMovement(ct, cf, LAYER_BOAT, revhint(cf, direction_hint));
|
||||||
}
|
}
|
||||||
|
|
||||||
moveBoatIfUsingOne(ct, cf);
|
moveBoatIfUsingOne(ct, cf, revhint(cf, direction_hint));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isTroll(m)) { makeTrollFootprints(ct); makeTrollFootprints(cf); }
|
if(isTroll(m)) { makeTrollFootprints(ct); makeTrollFootprints(cf); }
|
||||||
@ -3894,7 +3894,7 @@ int pickDownDirection(cell *c, flagtype mf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid) {
|
cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid, int& pushdir) {
|
||||||
if(subdir != 1 && subdir != -1) {
|
if(subdir != 1 && subdir != -1) {
|
||||||
subdir = 1;
|
subdir = 1;
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
@ -3910,6 +3910,7 @@ cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid) {
|
|||||||
if(valid(push.c)) return push.c;
|
if(valid(push.c)) return push.c;
|
||||||
if(c2->type&1) {
|
if(c2->type&1) {
|
||||||
push = push + wstep - subdir + wstep;
|
push = push + wstep - subdir + wstep;
|
||||||
|
pushdir = (push+wstep).spin;
|
||||||
if(valid(push.c)) return push.c;
|
if(valid(push.c)) return push.c;
|
||||||
}
|
}
|
||||||
if(gravityLevel(push.c) < gravityLevel(c2)) {
|
if(gravityLevel(push.c) < gravityLevel(c2)) {
|
||||||
@ -3920,6 +3921,7 @@ cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid) {
|
|||||||
if(gravityLevel(push.c) < gravityLevel(c2)) {
|
if(gravityLevel(push.c) < gravityLevel(c2)) {
|
||||||
push = push + wstep + 1 + wstep;
|
push = push + wstep + 1 + wstep;
|
||||||
}
|
}
|
||||||
|
pushdir = (push+wstep).spin;
|
||||||
if(valid(push.c)) return push.c;
|
if(valid(push.c)) return push.c;
|
||||||
}
|
}
|
||||||
return c2;
|
return c2;
|
||||||
@ -3939,9 +3941,10 @@ void beastAttack(cell *c, bool player) {
|
|||||||
if(c2->monst && c2->stuntime) {
|
if(c2->monst && c2->stuntime) {
|
||||||
cellwalker bull (c, d);
|
cellwalker bull (c, d);
|
||||||
int subdir = determinizeBullPush(bull);
|
int subdir = determinizeBullPush(bull);
|
||||||
cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return passable(c, c2, P_BLOW); });
|
int pushdir;
|
||||||
|
cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return passable(c, c2, P_BLOW); }, pushdir);
|
||||||
if(c3 && c3 != c2)
|
if(c3 && c3 != c2)
|
||||||
pushMonster(c3, c2);
|
pushMonster(c3, c2, pushdir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c2->wall == waThumperOff) {
|
if(c2->wall == waThumperOff) {
|
||||||
@ -3951,7 +3954,8 @@ void beastAttack(cell *c, bool player) {
|
|||||||
if(c2->wall == waThumperOn) {
|
if(c2->wall == waThumperOn) {
|
||||||
cellwalker bull (c, d);
|
cellwalker bull (c, d);
|
||||||
int subdir = determinizeBullPush(bull);
|
int subdir = determinizeBullPush(bull);
|
||||||
cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, c); });
|
int pushdir;
|
||||||
|
cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, c); }, pushdir);
|
||||||
if(c3 && c3 != c2)
|
if(c3 && c3 != c2)
|
||||||
pushThumper(c2, c3);
|
pushThumper(c2, c3);
|
||||||
}
|
}
|
||||||
@ -4002,13 +4006,13 @@ cell *moveNormal(cell *c, flagtype mf) {
|
|||||||
}
|
}
|
||||||
else if(m2) {
|
else if(m2) {
|
||||||
attackMonster(c2, AF_NORMAL | AF_MSG, m);
|
attackMonster(c2, AF_NORMAL | AF_MSG, m);
|
||||||
animateAttack(c, c2, LAYER_SMALL);
|
animateAttack(c, c2, LAYER_SMALL, d);
|
||||||
if(m == moFlailer && m2 == moIllusion)
|
if(m == moFlailer && m2 == moIllusion)
|
||||||
attackMonster(c, 0, m2);
|
attackMonster(c, 0, m2);
|
||||||
return c2;
|
return c2;
|
||||||
}
|
}
|
||||||
|
|
||||||
moveMonster(c2, c);
|
moveMonster(c2, c, d);
|
||||||
if(m == moRagingBull) beastAttack(c2, false);
|
if(m == moRagingBull) beastAttack(c2, false);
|
||||||
return c2;
|
return c2;
|
||||||
}
|
}
|
||||||
@ -4036,7 +4040,7 @@ cell *moveNormal(cell *c, flagtype mf) {
|
|||||||
if(!attacking) for(int i=0; i<nc; i++) {
|
if(!attacking) for(int i=0; i<nc; i++) {
|
||||||
cell *c2 = c->mov[posdir[i]];
|
cell *c2 = c->mov[posdir[i]];
|
||||||
if(!c->monst) c->monst = m;
|
if(!c->monst) c->monst = m;
|
||||||
moveMonster(c2, c);
|
moveMonster(c2, c, posdir[i]);
|
||||||
if(m == moRagingBull) beastAttack(c2, false);
|
if(m == moRagingBull) beastAttack(c2, false);
|
||||||
}
|
}
|
||||||
return c->mov[d];
|
return c->mov[d];
|
||||||
@ -4177,7 +4181,7 @@ void mountmove(cell *c, int spin, bool fp, int id) {
|
|||||||
void mountmove(cell *c, int spin, bool fp, cell *ppos) {
|
void mountmove(cell *c, int spin, bool fp, cell *ppos) {
|
||||||
for(int i=0; i<numplayers(); i++) {
|
for(int i=0; i<numplayers(); i++) {
|
||||||
if(playerpos(i) == ppos) {
|
if(playerpos(i) == ppos) {
|
||||||
animateMovement(ppos, c, LAYER_SMALL);
|
animateMovement(ppos, c, LAYER_SMALL, revhint(c, spin));
|
||||||
mountmove(c, spin, fp, i);
|
mountmove(c, spin, fp, i);
|
||||||
}
|
}
|
||||||
if(lastmountpos[i] == ppos && ppos != NULL) {
|
if(lastmountpos[i] == ppos && ppos != NULL) {
|
||||||
@ -4213,7 +4217,7 @@ void moveWorm(cell *c) {
|
|||||||
cell *cft = allcells[i];
|
cell *cft = allcells[i];
|
||||||
if(cft->monst != moTentacleGhost && cmt->monst != moTentacleGhost)
|
if(cft->monst != moTentacleGhost && cmt->monst != moTentacleGhost)
|
||||||
mountmove(cmt, cft->spn(cft->mondir), false, cft);
|
mountmove(cmt, cft->spn(cft->mondir), false, cft);
|
||||||
animateMovement(cft, cmt, LAYER_BIG);
|
animateMovement(cft, cmt, LAYER_BIG, cft->mondir);
|
||||||
}
|
}
|
||||||
c->monst = moNone;
|
c->monst = moNone;
|
||||||
if(c->mondir != NODIR) c->mov[c->mondir]->monst = moTentacleEscaping;
|
if(c->mondir != NODIR) c->mov[c->mondir]->monst = moTentacleEscaping;
|
||||||
@ -4283,9 +4287,9 @@ void moveWorm(cell *c) {
|
|||||||
|
|
||||||
for(int j=0; j<c->type; j++) if(c->mov[j] == goal) {
|
for(int j=0; j<c->type; j++) if(c->mov[j] == goal) {
|
||||||
goal->monst = eMonster(moWormwait + id);
|
goal->monst = eMonster(moWormwait + id);
|
||||||
moveEffect(goal, NULL, eMonster(moWormwait + id));
|
moveEffect(goal, NULL, eMonster(moWormwait + id), NOHINT);
|
||||||
|
|
||||||
animateMovement(c, goal, LAYER_BIG);
|
animateMovement(c, goal, LAYER_BIG, dir);
|
||||||
c->monst = eMonster(moWormtail + id);
|
c->monst = eMonster(moWormtail + id);
|
||||||
goal->mondir = c->spn(j);
|
goal->mondir = c->spn(j);
|
||||||
|
|
||||||
@ -4301,7 +4305,7 @@ void moveWorm(cell *c) {
|
|||||||
c3 = c2, c2 = c3->mov[c2->mondir];
|
c3 = c2, c2 = c3->mov[c2->mondir];
|
||||||
if(c3->monst != moTentacleGhost && c2->monst != moTentacleGhost)
|
if(c3->monst != moTentacleGhost && c2->monst != moTentacleGhost)
|
||||||
mountmove(c3, c3->mondir, true, c2);
|
mountmove(c3, c3->mondir, true, c2);
|
||||||
animateMovement(c2, c3, LAYER_BIG);
|
animateMovement(c2, c3, LAYER_BIG, c2->spin(c2->mondir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4314,7 +4318,7 @@ void moveWorm(cell *c) {
|
|||||||
}
|
}
|
||||||
c3 = c2, c2 = c3->mov[c2->mondir];
|
c3 = c2, c2 = c3->mov[c2->mondir];
|
||||||
mountmove(c3, c3->mondir, true, c2);
|
mountmove(c3, c3->mondir, true, c2);
|
||||||
animateMovement(c2, c3, LAYER_BIG);
|
animateMovement(c2, c3, LAYER_BIG, revhint(c2, c2->mondir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4415,9 +4419,9 @@ void moveivy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(mto && mto->cpdist) {
|
if(mto && mto->cpdist) {
|
||||||
animateMovement(mto->mov[sp], mto, LAYER_BIG);
|
animateMovement(mto->mov[sp], mto, LAYER_BIG, mto->spin(sp));
|
||||||
mto->monst = moIvyWait, mto->mondir = sp;
|
mto->monst = moIvyWait, mto->mondir = sp;
|
||||||
moveEffect(mto, NULL, moIvyWait);
|
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->mov[mto->mondir]->monst == moIvyHead) {
|
if(mto->mov[mto->mondir]->monst == moIvyHead) {
|
||||||
mto->monst = moIvyHead; co->monst = moIvyBranch;
|
mto->monst = moIvyHead; co->monst = moIvyBranch;
|
||||||
@ -4527,7 +4531,7 @@ void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
|
|||||||
if(!(mf & MF_NOATTACKS)) for(int j=0; j<c->type; j++)
|
if(!(mf & MF_NOATTACKS)) for(int j=0; j<c->type; j++)
|
||||||
if(c->mov[j] && canAttack(c, c->monst, c->mov[j], c->mov[j]->monst, af)) {
|
if(c->mov[j] && canAttack(c, c->monst, c->mov[j], c->mov[j]->monst, af)) {
|
||||||
attackMonster(c->mov[j], AF_NORMAL | AF_GETPLAYER | AF_MSG, c->monst);
|
attackMonster(c->mov[j], AF_NORMAL | AF_GETPLAYER | AF_MSG, c->monst);
|
||||||
animateAttack(c, c->mov[j], LAYER_SMALL);
|
animateAttack(c, c->mov[j], LAYER_SMALL, j);
|
||||||
c->aitmp = sval;
|
c->aitmp = sval;
|
||||||
// XLATC eagle
|
// XLATC eagle
|
||||||
return;
|
return;
|
||||||
@ -4540,7 +4544,7 @@ void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
moveMonster(from, c);
|
moveMonster(from, c, revhint(from, d));
|
||||||
from->aitmp = sval;
|
from->aitmp = sval;
|
||||||
}
|
}
|
||||||
c->aitmp = sval;
|
c->aitmp = sval;
|
||||||
@ -4612,12 +4616,12 @@ vector<cell*> hexdfs;
|
|||||||
// note: move from 'c' to 'from'!
|
// note: move from 'c' to 'from'!
|
||||||
void moveHexSnake(cell *from, cell *c, int d, bool mounted) {
|
void moveHexSnake(cell *from, cell *c, int d, bool mounted) {
|
||||||
if(from->wall == waBoat) from->wall = waSea;
|
if(from->wall == waBoat) from->wall = waSea;
|
||||||
moveEffect(from, c, c->monst);
|
moveEffect(from, c, c->monst, revhint(from, d));
|
||||||
from->monst = c->monst; from->mondir = d;
|
from->monst = c->monst; from->mondir = d; from->hitpoints = c->hitpoints;
|
||||||
c->monst = moHexSnakeTail;
|
c->monst = moHexSnakeTail;
|
||||||
preventbarriers(from);
|
preventbarriers(from);
|
||||||
|
|
||||||
animateMovement(c, from, LAYER_BIG);
|
animateMovement(c, from, LAYER_BIG, revhint(from, d));
|
||||||
mountmove(from, from->mondir, true, c);
|
mountmove(from, from->mondir, true, c);
|
||||||
|
|
||||||
cell *c2 = c, *c3=c2;
|
cell *c2 = c, *c3=c2;
|
||||||
@ -4625,7 +4629,7 @@ void moveHexSnake(cell *from, cell *c, int d, bool mounted) {
|
|||||||
if(a == ROCKSNAKELENGTH) { c2->monst = moNone, c3->mondir = NODIR; break; }
|
if(a == ROCKSNAKELENGTH) { c2->monst = moNone, c3->mondir = NODIR; break; }
|
||||||
if(c2->mondir == NODIR) break;
|
if(c2->mondir == NODIR) break;
|
||||||
mountmove(c2, c2->mondir, true, c2->mov[c2->mondir]);
|
mountmove(c2, c2->mondir, true, c2->mov[c2->mondir]);
|
||||||
animateMovement(c2->mov[c2->mondir], c2, LAYER_BIG);
|
animateMovement(c2->mov[c2->mondir], c2, LAYER_BIG, revhint(c2, c2->mondir));
|
||||||
c3 = c2, c2 = c3->mov[c2->mondir];
|
c3 = c2, c2 = c3->mov[c2->mondir];
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
@ -4787,7 +4791,7 @@ void movemutant() {
|
|||||||
c2->monst = moMutant;
|
c2->monst = moMutant;
|
||||||
c2->mondir = c->spn(j);
|
c2->mondir = c->spn(j);
|
||||||
c2->stuntime = mutantphase;
|
c2->stuntime = mutantphase;
|
||||||
animateMovement(c, c2, LAYER_BIG);
|
animateMovement(c, c2, LAYER_BIG, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4823,7 +4827,7 @@ void moveshadow() {
|
|||||||
cell* where = shpos[p][cshpos];
|
cell* where = shpos[p][cshpos];
|
||||||
if(where && where->monst == moNone && where->cpdist && where->land == laGraveyard &&
|
if(where && where->monst == moNone && where->cpdist && where->land == laGraveyard &&
|
||||||
!sword::at(where)) {
|
!sword::at(where)) {
|
||||||
if(shfrom) animateMovement(shfrom, where, LAYER_SMALL);
|
if(shfrom) animateMovement(shfrom, where, LAYER_SMALL, NOHINT);
|
||||||
where->monst = moShadow;
|
where->monst = moShadow;
|
||||||
where->hitpoints = p;
|
where->hitpoints = p;
|
||||||
where->stuntime = 0;
|
where->stuntime = 0;
|
||||||
@ -4881,7 +4885,7 @@ void moveghosts() {
|
|||||||
addMessage(XLAT("%The1 scares %the2 a bit!", c->monst, c2->monst));
|
addMessage(XLAT("%The1 scares %the2 a bit!", c->monst, c2->monst));
|
||||||
c2->stuntime = 1;
|
c2->stuntime = 1;
|
||||||
}
|
}
|
||||||
else moveMonster(c2, c);
|
else moveMonster(c2, c, d);
|
||||||
|
|
||||||
}
|
}
|
||||||
nextghost: ;
|
nextghost: ;
|
||||||
@ -5249,7 +5253,7 @@ void movegolems(flagtype flags) {
|
|||||||
else if((flags & AF_CRUSH) && !canAttack(c, m, c2, c2->monst, flags ^ AF_CRUSH ^ AF_MUSTKILL))
|
else if((flags & AF_CRUSH) && !canAttack(c, m, c2, c2->monst, flags ^ AF_CRUSH ^ AF_MUSTKILL))
|
||||||
markOrb(itOrbEmpathy), markOrb(itOrbSlaying);
|
markOrb(itOrbEmpathy), markOrb(itOrbSlaying);
|
||||||
attackMonster(c2, flags | AF_MSG, m);
|
attackMonster(c2, flags | AF_MSG, m);
|
||||||
animateAttack(c, c2, LAYER_SMALL);
|
animateAttack(c, c2, LAYER_SMALL, dir);
|
||||||
produceGhost(c2, m2, m);
|
produceGhost(c2, m2, m);
|
||||||
sideAttack(c, dir, m, 0);
|
sideAttack(c, dir, m, 0);
|
||||||
if(revenge) c->monst = m = moPrincessArmed;
|
if(revenge) c->monst = m = moPrincessArmed;
|
||||||
@ -5261,9 +5265,9 @@ void movegolems(flagtype flags) {
|
|||||||
else {
|
else {
|
||||||
passable_for(m, c2, c, P_DEADLY);
|
passable_for(m, c2, c, P_DEADLY);
|
||||||
DEBT("move");
|
DEBT("move");
|
||||||
moveMonster(c2, c);
|
moveMonster(c2, c, dir);
|
||||||
if(m != moTameBomberbird && m != moFriendlyGhost)
|
if(m != moTameBomberbird && m != moFriendlyGhost)
|
||||||
moveBoatIfUsingOne(c2, c);
|
moveBoatIfUsingOne(c2, c, dir);
|
||||||
|
|
||||||
if(c2->monst == m) {
|
if(c2->monst == m) {
|
||||||
if(m == moGolem) c2->monst = moGolemMoved;
|
if(m == moGolem) c2->monst = moGolemMoved;
|
||||||
@ -7396,7 +7400,8 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(c2->wall == waThumperOn && !c2->monst && !nonAdjacentPlayer(c2, cwt.c)) {
|
if(c2->wall == waThumperOn && !c2->monst && !nonAdjacentPlayer(c2, cwt.c)) {
|
||||||
cell *c3 = determinePush(cwt, c2, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, cwt.c); });
|
int pushdir;
|
||||||
|
cell *c3 = determinePush(cwt, c2, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, cwt.c); }, pushdir);
|
||||||
if(c3 == c2) {
|
if(c3 == c2) {
|
||||||
if(checkonly) return false;
|
if(checkonly) return false;
|
||||||
addMessage(XLAT("No room to push %the1.", c2->wall));
|
addMessage(XLAT("No room to push %the1.", c2->wall));
|
||||||
@ -7446,7 +7451,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(checkonly) return true;
|
if(checkonly) return true;
|
||||||
moveBoat(c2, cwt.c);
|
moveBoat(c2, cwt.c, d);
|
||||||
boatmove = true;
|
boatmove = true;
|
||||||
goto boatjump;
|
goto boatjump;
|
||||||
}
|
}
|
||||||
@ -7462,8 +7467,8 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
if(checkonly) return true;
|
if(checkonly) return true;
|
||||||
if(c2->item && !cwt.c->item) moveItem(c2, cwt.c, false), boatmove = true;
|
if(c2->item && !cwt.c->item) moveItem(c2, cwt.c, false), boatmove = true;
|
||||||
placeWater(c2, cwt.c);
|
placeWater(c2, cwt.c);
|
||||||
moveBoat(c2, cwt.c);
|
moveBoat(c2, cwt.c, d);
|
||||||
c2->mondir = neighborId(c2, cwt.c);
|
c2->mondir = revhint(cwt.c, d);
|
||||||
if(c2->item) boatmove = !boatmove;
|
if(c2->item) boatmove = !boatmove;
|
||||||
goto boatjump;
|
goto boatjump;
|
||||||
}
|
}
|
||||||
@ -7495,7 +7500,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
|
|
||||||
if(checkonly) { c2->wall = save_c2; cwt.c->wall = save_cw; return true; }
|
if(checkonly) { c2->wall = save_c2; cwt.c->wall = save_cw; return true; }
|
||||||
addMessage(XLAT("You push %the1 behind you!", waBigStatue));
|
addMessage(XLAT("You push %the1 behind you!", waBigStatue));
|
||||||
animateMovement(c2, cwt.c, LAYER_BOAT);
|
animateMovement(c2, cwt.c, LAYER_BOAT, cwt.c->spin(d));
|
||||||
goto statuejump;
|
goto statuejump;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7522,7 +7527,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
playSound(c2, "hit-axe" + pick123());
|
playSound(c2, "hit-axe" + pick123());
|
||||||
c2->wall = waNone;
|
c2->wall = waNone;
|
||||||
sideAttack(cwt.c, d, moPlayer, 0);
|
sideAttack(cwt.c, d, moPlayer, 0);
|
||||||
animateAttack(cwt.c, c2, LAYER_SMALL);
|
animateAttack(cwt.c, c2, LAYER_SMALL, d);
|
||||||
}
|
}
|
||||||
else if(c2->wall == waBigTree) {
|
else if(c2->wall == waBigTree) {
|
||||||
drawParticles(c2, winf[c2->wall].color, 8);
|
drawParticles(c2, winf[c2->wall].color, 8);
|
||||||
@ -7530,13 +7535,13 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
playSound(c2, "hit-axe" + pick123());
|
playSound(c2, "hit-axe" + pick123());
|
||||||
c2->wall = waSmallTree;
|
c2->wall = waSmallTree;
|
||||||
sideAttack(cwt.c, d, moPlayer, 0);
|
sideAttack(cwt.c, d, moPlayer, 0);
|
||||||
animateAttack(cwt.c, c2, LAYER_SMALL);
|
animateAttack(cwt.c, c2, LAYER_SMALL, d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!peace::on) {
|
if(!peace::on) {
|
||||||
addMessage(XLAT("You swing your sword at the mirror."));
|
addMessage(XLAT("You swing your sword at the mirror."));
|
||||||
sideAttack(cwt.c, d, moPlayer, 0);
|
sideAttack(cwt.c, d, moPlayer, 0);
|
||||||
animateAttack(cwt.c, c2, LAYER_SMALL);
|
animateAttack(cwt.c, c2, LAYER_SMALL, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(survivalist && isHaunted(c2->land))
|
if(survivalist && isHaunted(c2->land))
|
||||||
@ -7601,9 +7606,10 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
// pushto=c2 means that the monster is not killed and thus
|
// pushto=c2 means that the monster is not killed and thus
|
||||||
// still counts for lightning in monstersnear
|
// still counts for lightning in monstersnear
|
||||||
cell *pushto = NULL;
|
cell *pushto = NULL;
|
||||||
|
int pushdir = 0;
|
||||||
if(isStunnable(c2->monst) && c2->hitpoints > 1) {
|
if(isStunnable(c2->monst) && c2->hitpoints > 1) {
|
||||||
if(monsterPushable(c2))
|
if(monsterPushable(c2))
|
||||||
pushto = determinePush(cwt, c2, subdir, [c2] (cell *c) { return passable(c, c2, P_BLOW); });
|
pushto = determinePush(cwt, c2, subdir, [c2] (cell *c) { return passable(c, c2, P_BLOW); }, pushdir);
|
||||||
else
|
else
|
||||||
pushto = c2;
|
pushto = c2;
|
||||||
}
|
}
|
||||||
@ -7661,8 +7667,8 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
// salamanders are stunned for longer time when pushed into a wall
|
// salamanders are stunned for longer time when pushed into a wall
|
||||||
if(c2->monst == moSalamander && (pushto == c2 || !pushto)) c2->stuntime = 10;
|
if(c2->monst == moSalamander && (pushto == c2 || !pushto)) c2->stuntime = 10;
|
||||||
if(!c2->monst) produceGhost(c2, m, moPlayer);
|
if(!c2->monst) produceGhost(c2, m, moPlayer);
|
||||||
if(pushto && pushto != c2) pushMonster(pushto, c2);
|
if(pushto && pushto != c2) pushMonster(pushto, c2, pushdir);
|
||||||
animateAttack(cwt.c, c2, LAYER_SMALL);
|
animateAttack(cwt.c, c2, LAYER_SMALL, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7840,11 +7846,12 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
|
|
||||||
stabbingAttack(cwt.c, c2, moPlayer);
|
stabbingAttack(cwt.c, c2, moPlayer);
|
||||||
cell *c1 = cwt.c;
|
cell *c1 = cwt.c;
|
||||||
|
int d = cwt.spin;
|
||||||
cwt += wstep;
|
cwt += wstep;
|
||||||
if(switchplaces)
|
if(switchplaces)
|
||||||
animateReplacement(c1, cwt.c, LAYER_SMALL);
|
animateReplacement(c1, cwt.c, LAYER_SMALL, d, cwt.spin);
|
||||||
else
|
else
|
||||||
animateMovement(c1, cwt.c, LAYER_SMALL);
|
animateMovement(c1, cwt.c, LAYER_SMALL, d);
|
||||||
|
|
||||||
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK | mirror::GO);
|
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK | mirror::GO);
|
||||||
|
|
||||||
|
21
goldberg.cpp
21
goldberg.cpp
@ -579,14 +579,17 @@ namespace hr { namespace gp {
|
|||||||
dialog::init(XLAT("Goldberg"));
|
dialog::init(XLAT("Goldberg"));
|
||||||
|
|
||||||
bool show_nonthree = !(texture_remap && (S7&1));
|
bool show_nonthree = !(texture_remap && (S7&1));
|
||||||
|
bool show_bitrunc = !(texture_remap && !(S7&1));
|
||||||
|
|
||||||
if(show_nonthree) {
|
if(show_nonthree) {
|
||||||
dialog::addBoolItem(XLAT("OFF"), param == loc(1,0), 'a');
|
dialog::addBoolItem(XLAT("OFF"), param == loc(1,0), 'a');
|
||||||
dialog::lastItem().value = "GP(1,0)";
|
dialog::lastItem().value = "GP(1,0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog::addBoolItem(XLAT("bitruncated"), param == loc(1,1), 'b');
|
if(show_bitrunc) {
|
||||||
dialog::lastItem().value = "GP(1,1)";
|
dialog::addBoolItem(XLAT("bitruncated"), param == loc(1,1), 'b');
|
||||||
|
dialog::lastItem().value = "GP(1,1)";
|
||||||
|
}
|
||||||
|
|
||||||
if(show_nonthree) {
|
if(show_nonthree) {
|
||||||
dialog::addBoolItem(XLAT("chamfered"), param == loc(2,0), 'c');
|
dialog::addBoolItem(XLAT("chamfered"), param == loc(2,0), 'c');
|
||||||
@ -599,10 +602,12 @@ namespace hr { namespace gp {
|
|||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
dialog::addSelItem("x", its(config.first), 'x');
|
dialog::addSelItem("x", its(config.first), 'x');
|
||||||
dialog::addSelItem("y", its(config.second), 'y');
|
dialog::addSelItem("y", its(config.second), 'y');
|
||||||
|
|
||||||
if((config.first-config.second)%3 && !show_nonthree)
|
if((config.first-config.second)%3 && !show_nonthree)
|
||||||
dialog::addInfo("This pattern needs x-y divisible by 3");
|
dialog::addInfo(XLAT("This pattern needs x-y divisible by 3"));
|
||||||
else
|
else if(config == loc(1,1) && !show_bitrunc)
|
||||||
|
dialog::addInfo(XLAT("Select bitruncated from the previous menu"));
|
||||||
|
else
|
||||||
dialog::addBoolItem(XLAT("select"), param == internal_representation(config), 'f');
|
dialog::addBoolItem(XLAT("select"), param == internal_representation(config), 'f');
|
||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
@ -610,17 +615,17 @@ namespace hr { namespace gp {
|
|||||||
dialog::addBack();
|
dialog::addBack();
|
||||||
dialog::display();
|
dialog::display();
|
||||||
|
|
||||||
keyhandler = [show_nonthree, texture_remap] (int sym, int uni) {
|
keyhandler = [show_nonthree, show_bitrunc, texture_remap] (int sym, int uni) {
|
||||||
dialog::handleNavigation(sym, uni);
|
dialog::handleNavigation(sym, uni);
|
||||||
if(uni == 'a' && show_nonthree)
|
if(uni == 'a' && show_nonthree)
|
||||||
whirl_set(loc(1, 0), texture_remap);
|
whirl_set(loc(1, 0), texture_remap);
|
||||||
else if(uni == 'b')
|
else if(uni == 'b' && show_bitrunc)
|
||||||
whirl_set(loc(1, 1), texture_remap);
|
whirl_set(loc(1, 1), texture_remap);
|
||||||
else if(uni == 'c' && show_nonthree)
|
else if(uni == 'c' && show_nonthree)
|
||||||
whirl_set(loc(2, 0), texture_remap);
|
whirl_set(loc(2, 0), texture_remap);
|
||||||
else if(uni == 'd')
|
else if(uni == 'd')
|
||||||
whirl_set(loc(3, 0), texture_remap);
|
whirl_set(loc(3, 0), texture_remap);
|
||||||
else if(uni == 'f' && (show_nonthree || (config.first-config.second)%3 == 0))
|
else if(uni == 'f' && (config == loc(1,1) ? show_bitrunc : (show_nonthree || (config.first-config.second)%3 == 0)))
|
||||||
whirl_set(config, texture_remap);
|
whirl_set(config, texture_remap);
|
||||||
else if(uni == 'x')
|
else if(uni == 'x')
|
||||||
dialog::editNumber(config.first, 1, 10, 1, 1, "x", helptext());
|
dialog::editNumber(config.first, 1, 10, 1, 1, "x", helptext());
|
||||||
|
94
graph.cpp
94
graph.cpp
@ -1826,7 +1826,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
|||||||
|
|
||||||
if(isIvy(c) || isWorm(c) || isMutantIvy(c) || c->monst == moFriendlyIvy) {
|
if(isIvy(c) || isWorm(c) || isMutantIvy(c) || c->monst == moFriendlyIvy) {
|
||||||
|
|
||||||
if((m == moHexSnake || m == moHexSnakeTail) && c->land == laSnakeNest) {
|
if((m == moHexSnake || m == moHexSnakeTail) && c->hitpoints == 2) {
|
||||||
int d = c->mondir;
|
int d = c->mondir;
|
||||||
if(d == NODIR)
|
if(d == NODIR)
|
||||||
forCellIdEx(c2, i, c)
|
forCellIdEx(c2, i, c)
|
||||||
@ -2090,7 +2090,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
|||||||
Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir));
|
Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir));
|
||||||
}
|
}
|
||||||
else if(gp::on) {
|
else if(gp::on) {
|
||||||
transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c);
|
transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c, c->mondir);
|
||||||
Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length);
|
Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2139,6 +2139,10 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
bool mirr = multi::players > 1 ? multi::player[i].mirrored : cwt.mirrored;
|
||||||
|
if(mirr) Vs = Vs * Mirror;
|
||||||
|
}
|
||||||
shmup::cpid = i;
|
shmup::cpid = i;
|
||||||
|
|
||||||
drawPlayerEffects(Vs, c, true);
|
drawPlayerEffects(Vs, c, true);
|
||||||
@ -2562,7 +2566,7 @@ void drawMovementArrows(cell *c, transmatrix V) {
|
|||||||
int sd = md.subdir;
|
int sd = md.subdir;
|
||||||
queuepoly(inverse(Centered) * rgpushxto0(Centered * tC0(V)) * rspintox(Centered*tC0(V)) * spin(-sd * M_PI/S7) * xpush(0.2), shArrow, col);
|
queuepoly(inverse(Centered) * rgpushxto0(Centered * tC0(V)) * rspintox(Centered*tC0(V)) * spin(-sd * M_PI/S7) * xpush(0.2), shArrow, col);
|
||||||
}
|
}
|
||||||
else break;
|
else if(!confusingGeometry()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3425,6 +3429,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
#if CAP_TEXTURE
|
#if CAP_TEXTURE
|
||||||
if(texture::saving) {
|
if(texture::saving) {
|
||||||
texture::config.apply(c, V, 0xFFFFFFFF);
|
texture::config.apply(c, V, 0xFFFFFFFF);
|
||||||
|
draw_qfi(c, V, 0xFFFFFFFF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4962,15 +4967,15 @@ void drawMarkers() {
|
|||||||
|
|
||||||
if((vid.axes == 4 || (vid.axes == 1 && !mousing)) && !shmup::on) {
|
if((vid.axes == 4 || (vid.axes == 1 && !mousing)) && !shmup::on) {
|
||||||
if(multi::players == 1) {
|
if(multi::players == 1) {
|
||||||
forCellAll(c2, cwt.c) IG(c2) drawMovementArrows(c2, Gm(c2));
|
forCellIdAll(c2, d, cwt.c) IG(c2) drawMovementArrows(c2, confusingGeometry() ? Gm(cwt.c) * shmup::calc_relative_matrix(c2, cwt.c, d) : Gm(c2));
|
||||||
}
|
}
|
||||||
else if(multi::players > 1) for(int p=0; p<multi::players; p++) {
|
else if(multi::players > 1) for(int p=0; p<multi::players; p++) {
|
||||||
if(multi::playerActive(p) && (vid.axes == 4 || !drawstaratvec(multi::mdx[p], multi::mdy[p])))
|
if(multi::playerActive(p) && (vid.axes == 4 || !drawstaratvec(multi::mdx[p], multi::mdy[p])))
|
||||||
forCellAll(c2, multi::player[p].c) IG(c2) {
|
forCellIdAll(c2, d, multi::player[p].c) IG(c2) {
|
||||||
multi::cpid = p;
|
multi::cpid = p;
|
||||||
dynamicval<transmatrix> ttm(cwtV, multi::whereis[p]);
|
dynamicval<transmatrix> ttm(cwtV, multi::whereis[p]);
|
||||||
dynamicval<cellwalker> tcw(cwt, multi::player[p]);
|
dynamicval<cellwalker> tcw(cwt, multi::player[p]);
|
||||||
drawMovementArrows(c2, Gm(c2));
|
drawMovementArrows(c2, confusingGeometry() ? Gm(cwt.c) * shmup::calc_relative_matrix(c2, cwt.c, d) : Gm(c2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5739,51 +5744,68 @@ void resetGeometry() {
|
|||||||
map<cell*, animation> animations[ANIMLAYERS];
|
map<cell*, animation> animations[ANIMLAYERS];
|
||||||
unordered_map<cell*, transmatrix> gmatrix, gmatrix0;
|
unordered_map<cell*, transmatrix> gmatrix, gmatrix0;
|
||||||
|
|
||||||
void animateMovement(cell *src, cell *tgt, int layer) {
|
int revhint(cell *c, int hint) {
|
||||||
|
if(hint >= 0 && hint < c->type) return c->spin(hint);
|
||||||
|
else return hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compute_relamatrix(cell *src, cell *tgt, int direction_hint, transmatrix& T) {
|
||||||
|
if(confusingGeometry()) {
|
||||||
|
T = shmup::calc_relative_matrix(src, tgt, revhint(src, direction_hint));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(gmatrix.count(src) && gmatrix.count(tgt))
|
||||||
|
T = inverse(gmatrix[tgt]) * gmatrix[src];
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void animateMovement(cell *src, cell *tgt, int layer, int direction_hint) {
|
||||||
if(vid.mspeed >= 5) return; // no animations!
|
if(vid.mspeed >= 5) return; // no animations!
|
||||||
if(confusingGeometry()) return;
|
transmatrix T;
|
||||||
if(gmatrix.count(src) && gmatrix.count(tgt)) {
|
if(!compute_relamatrix(src, tgt, direction_hint, T)) return;
|
||||||
animation& a = animations[layer][tgt];
|
animation& a = animations[layer][tgt];
|
||||||
if(animations[layer].count(src)) {
|
if(animations[layer].count(src)) {
|
||||||
a = animations[layer][src];
|
a = animations[layer][src];
|
||||||
a.wherenow = inverse(gmatrix[tgt]) * gmatrix[src] * a.wherenow;
|
a.wherenow = T * a.wherenow;
|
||||||
animations[layer].erase(src);
|
animations[layer].erase(src);
|
||||||
a.attacking = 0;
|
a.attacking = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.ltick = ticks;
|
a.ltick = ticks;
|
||||||
a.wherenow = inverse(gmatrix[tgt]) * gmatrix[src];
|
a.wherenow = T;
|
||||||
a.footphase = 0;
|
a.footphase = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void animateAttack(cell *src, cell *tgt, int layer) {
|
void animateAttack(cell *src, cell *tgt, int layer, int direction_hint) {
|
||||||
if(vid.mspeed >= 5) return; // no animations!
|
if(vid.mspeed >= 5) return; // no animations!
|
||||||
if(gmatrix.count(src) && gmatrix.count(tgt)) {
|
transmatrix T;
|
||||||
bool newanim = !animations[layer].count(src);
|
if(!compute_relamatrix(src, tgt, direction_hint, T)) return;
|
||||||
animation& a = animations[layer][src];
|
bool newanim = !animations[layer].count(src);
|
||||||
a.attacking = 1;
|
animation& a = animations[layer][src];
|
||||||
a.attackat = rspintox(tC0(inverse(gmatrix[src]) * gmatrix[tgt])) * xpush(hdist(gmatrix[src]*C0, gmatrix[tgt]*C0) / 3);
|
a.attacking = 1;
|
||||||
if(newanim) a.wherenow = Id, a.ltick = ticks, a.footphase = 0;
|
a.attackat = rspintox(tC0(inverse(T))) * xpush(hdist0(T*C0) / 3);
|
||||||
}
|
if(newanim) a.wherenow = Id, a.ltick = ticks, a.footphase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<pair<cell*, animation> > animstack;
|
vector<pair<cell*, animation> > animstack;
|
||||||
|
|
||||||
void indAnimateMovement(cell *src, cell *tgt, int layer) {
|
void indAnimateMovement(cell *src, cell *tgt, int layer, int direction_hint) {
|
||||||
if(vid.mspeed >= 5) return; // no animations!
|
if(vid.mspeed >= 5) return; // no animations!
|
||||||
if(confusingGeometry()) return;
|
|
||||||
if(animations[layer].count(tgt)) {
|
if(animations[layer].count(tgt)) {
|
||||||
animation res = animations[layer][tgt];
|
animation res = animations[layer][tgt];
|
||||||
animations[layer].erase(tgt);
|
animations[layer].erase(tgt);
|
||||||
animateMovement(src, tgt, layer);
|
animateMovement(src, tgt, layer, direction_hint);
|
||||||
if(animations[layer].count(tgt))
|
if(animations[layer].count(tgt))
|
||||||
animstack.push_back(make_pair(tgt, animations[layer][tgt]));
|
animstack.push_back(make_pair(tgt, animations[layer][tgt]));
|
||||||
animations[layer][tgt] = res;
|
animations[layer][tgt] = res;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
animateMovement(src, tgt, layer);
|
animateMovement(src, tgt, layer, direction_hint);
|
||||||
if(animations[layer].count(tgt)) {
|
if(animations[layer].count(tgt)) {
|
||||||
animstack.push_back(make_pair(tgt, animations[layer][tgt]));
|
animstack.push_back(make_pair(tgt, animations[layer][tgt]));
|
||||||
animations[layer].erase(tgt);
|
animations[layer].erase(tgt);
|
||||||
@ -5797,13 +5819,13 @@ void commitAnimations(int layer) {
|
|||||||
animstack.clear();
|
animstack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void animateReplacement(cell *a, cell *b, int layer) {
|
void animateReplacement(cell *a, cell *b, int layer, int direction_hinta, int direction_hintb) {
|
||||||
if(vid.mspeed >= 5) return; // no animations!
|
if(vid.mspeed >= 5) return; // no animations!
|
||||||
static cell c1;
|
static cell c1;
|
||||||
gmatrix[&c1] = gmatrix[b];
|
gmatrix[&c1] = gmatrix[b];
|
||||||
if(animations[layer].count(b)) animations[layer][&c1] = animations[layer][b];
|
if(animations[layer].count(b)) animations[layer][&c1] = animations[layer][b];
|
||||||
animateMovement(a, b, layer);
|
animateMovement(a, b, layer, direction_hinta);
|
||||||
animateMovement(&c1, a, layer);
|
animateMovement(&c1, a, layer, direction_hintb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawBug(const cellwalker& cw, int col) {
|
void drawBug(const cellwalker& cw, int col) {
|
||||||
|
25
hyper.h
25
hyper.h
@ -2,9 +2,9 @@
|
|||||||
// It is quite chaotic.
|
// It is quite chaotic.
|
||||||
|
|
||||||
// version numbers
|
// version numbers
|
||||||
#define VER "10.4b"
|
#define VER "10.4c"
|
||||||
#define VERNUM 10402
|
#define VERNUM 10403
|
||||||
#define VERNUM_HEX 0xA0B2
|
#define VERNUM_HEX 0xA0B3
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ bool movepcto(int d, int subdir = 1, bool checkonly = false);
|
|||||||
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill = 0);
|
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill = 0);
|
||||||
bool earthMove(cell *from, int dir);
|
bool earthMove(cell *from, int dir);
|
||||||
void messageKill(eMonster killer, eMonster victim);
|
void messageKill(eMonster killer, eMonster victim);
|
||||||
void moveMonster(cell *ct, cell *cf);
|
void moveMonster(cell *ct, cell *cf, int direction_hint);
|
||||||
int palaceHP();
|
int palaceHP();
|
||||||
void placeLocalOrbs(cell *c);
|
void placeLocalOrbs(cell *c);
|
||||||
int elementalKills();
|
int elementalKills();
|
||||||
@ -654,7 +654,7 @@ namespace shmup {
|
|||||||
|
|
||||||
void virtualRebase(cell*& base, transmatrix& at, bool tohex);
|
void virtualRebase(cell*& base, transmatrix& at, bool tohex);
|
||||||
void virtualRebase(shmup::monster *m, bool tohex);
|
void virtualRebase(shmup::monster *m, bool tohex);
|
||||||
transmatrix calc_relative_matrix(cell *c, cell *c1);
|
transmatrix calc_relative_matrix(cell *c, cell *c1, int direction_hint);
|
||||||
void fixStorage();
|
void fixStorage();
|
||||||
void addShmupHelp(string& out);
|
void addShmupHelp(string& out);
|
||||||
void activateArrow(cell *c);
|
void activateArrow(cell *c);
|
||||||
@ -665,6 +665,8 @@ namespace shmup {
|
|||||||
void popmonsters();
|
void popmonsters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int NOHINT = -1;
|
||||||
|
|
||||||
// graph
|
// graph
|
||||||
|
|
||||||
void showMissionScreen();
|
void showMissionScreen();
|
||||||
@ -1552,16 +1554,16 @@ struct animation {
|
|||||||
extern map<cell*, animation> animations[ANIMLAYERS];
|
extern map<cell*, animation> animations[ANIMLAYERS];
|
||||||
extern unordered_map<cell*, transmatrix> gmatrix, gmatrix0;
|
extern unordered_map<cell*, transmatrix> gmatrix, gmatrix0;
|
||||||
|
|
||||||
void animateAttack(cell *src, cell *tgt, int layer);
|
void animateAttack(cell *src, cell *tgt, int layer, int direction_hint);
|
||||||
|
|
||||||
void animateMovement(cell *src, cell *tgt, int layer);
|
void animateMovement(cell *src, cell *tgt, int layer, int direction_hint);
|
||||||
|
|
||||||
// for animations which might use the same locations,
|
// for animations which might use the same locations,
|
||||||
// such as replacements or multi-tile monsters
|
// such as replacements or multi-tile monsters
|
||||||
void indAnimateMovement(cell *src, cell *tgt, int layer);
|
void indAnimateMovement(cell *src, cell *tgt, int layer, int direction_hint);
|
||||||
void commitAnimations(int layer);
|
void commitAnimations(int layer);
|
||||||
|
|
||||||
void animateReplacement(cell *a, cell *b, int layer);
|
void animateReplacement(cell *a, cell *b, int layer, int direction_hinta, int direction_hintb);
|
||||||
void fallingFloorAnimation(cell *c, eWall w = waNone, eMonster m = moNone);
|
void fallingFloorAnimation(cell *c, eWall w = waNone, eMonster m = moNone);
|
||||||
void fallingMonsterAnimation(cell *c, eMonster m, int id = multi::cpid);
|
void fallingMonsterAnimation(cell *c, eMonster m, int id = multi::cpid);
|
||||||
|
|
||||||
@ -2780,7 +2782,6 @@ namespace texture {
|
|||||||
void showMenu();
|
void showMenu();
|
||||||
|
|
||||||
void drawPixel(cell *c, hyperpoint h, int col);
|
void drawPixel(cell *c, hyperpoint h, int col);
|
||||||
|
|
||||||
extern cell *where;
|
extern cell *where;
|
||||||
// compute 'c' automatically, based on the hint in 'where'
|
// compute 'c' automatically, based on the hint in 'where'
|
||||||
void drawPixel(hyperpoint h, int col);
|
void drawPixel(hyperpoint h, int col);
|
||||||
@ -3512,4 +3513,8 @@ void gdpush(int t);
|
|||||||
|
|
||||||
extern int fontscale;
|
extern int fontscale;
|
||||||
|
|
||||||
|
bool confusingGeometry();
|
||||||
|
|
||||||
|
int revhint(cell *c, int hint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1626,7 +1626,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
|||||||
for(int t=0; t<c->type; t++) if(c->mov[t]->mpdist > c->mpdist && !pseudohept(c->mov[t]))
|
for(int t=0; t<c->type; t++) if(c->mov[t]->mpdist > c->mpdist && !pseudohept(c->mov[t]))
|
||||||
i = t;
|
i = t;
|
||||||
if(i != -1 && !peace::on)
|
if(i != -1 && !peace::on)
|
||||||
generateSnake(c, i);
|
generateSnake(c, i, 1);
|
||||||
}
|
}
|
||||||
else if(hrand(16000) < 50+items[itRedGem]+yendor::hardness() && (nonbitrunc?hrand(10)<3:!ishept(c)) && !c->monst)
|
else if(hrand(16000) < 50+items[itRedGem]+yendor::hardness() && (nonbitrunc?hrand(10)<3:!ishept(c)) && !c->monst)
|
||||||
c->monst = moRedTroll,
|
c->monst = moRedTroll,
|
||||||
@ -1641,7 +1641,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
|||||||
for(int t=0; t<c->type; t++) if(c->mov[t]->mpdist > c->mpdist)
|
for(int t=0; t<c->type; t++) if(c->mov[t]->mpdist > c->mpdist)
|
||||||
gooddir.push_back(t);
|
gooddir.push_back(t);
|
||||||
if(size(gooddir))
|
if(size(gooddir))
|
||||||
generateSnake(c, gooddir[hrand(size(gooddir))]);
|
generateSnake(c, gooddir[hrand(size(gooddir))], 2);
|
||||||
}
|
}
|
||||||
else if(hrand(10000) < items[itSnake] - 10 + yendor::hardness() && !c->monst && !c->wall && !peace::on) {
|
else if(hrand(10000) < items[itSnake] - 10 + yendor::hardness() && !c->monst && !c->wall && !peace::on) {
|
||||||
c->monst = pick(moRedTroll, moMiner, moSkeleton, moBomberbird);
|
c->monst = pick(moRedTroll, moMiner, moSkeleton, moBomberbird);
|
||||||
@ -1970,7 +1970,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
|||||||
c->monst = moMonkey;
|
c->monst = moMonkey;
|
||||||
else if(hrand(80000) < 5 + items[itRuby] + yendor::hardness())
|
else if(hrand(80000) < 5 + items[itRuby] + yendor::hardness())
|
||||||
c->monst = moEagle;
|
c->monst = moEagle;
|
||||||
else if(ishept(c) && c != currentmap->gamestart() && hrand(4000) < 300 + items[itRuby] && !c->monst) {
|
else if(pseudohept(c) && c != currentmap->gamestart() && hrand(4000) < 300 + items[itRuby] && !c->monst) {
|
||||||
int hardchance = items[itRuby] + yendor::hardness();
|
int hardchance = items[itRuby] + yendor::hardness();
|
||||||
if(hardchance > 25) hardchance = 25;
|
if(hardchance > 25) hardchance = 25;
|
||||||
bool hardivy = hrand(100) < hardchance;
|
bool hardivy = hrand(100) < hardchance;
|
||||||
|
@ -547,6 +547,12 @@ namespace mapeditor {
|
|||||||
if((isWorm(c) || isIvy(c) || isMutantIvy(c)) && c->mov[cdir] &&
|
if((isWorm(c) || isIvy(c) || isMutantIvy(c)) && c->mov[cdir] &&
|
||||||
!isWorm(c->mov[cdir]) && !isIvy(c->mov[cdir]))
|
!isWorm(c->mov[cdir]) && !isIvy(c->mov[cdir]))
|
||||||
c->mondir = NODIR;
|
c->mondir = NODIR;
|
||||||
|
|
||||||
|
if(c->monst == moMimic) {
|
||||||
|
c->monst = moNone;
|
||||||
|
mirror::createMirror(cellwalker(c, cdir, true), 0);
|
||||||
|
c->monst = moMimic;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
c->item = eItem(paintwhat);
|
c->item = eItem(paintwhat);
|
||||||
@ -1054,6 +1060,8 @@ namespace mapeditor {
|
|||||||
displaymm('d', 8, 8+fs*7, 2, vid.fsize, XLAT("d = draw"), 0);
|
displaymm('d', 8, 8+fs*7, 2, vid.fsize, XLAT("d = draw"), 0);
|
||||||
displaymm('l', 8, 8+fs*8, 2, vid.fsize, XLAT("l = line"), 0);
|
displaymm('l', 8, 8+fs*8, 2, vid.fsize, XLAT("l = line"), 0);
|
||||||
displaymm('c', 8, 8+fs*9, 2, vid.fsize, XLAT("c = circle"), 0);
|
displaymm('c', 8, 8+fs*9, 2, vid.fsize, XLAT("c = circle"), 0);
|
||||||
|
int s = size(texture::config.data.pixels_to_draw);
|
||||||
|
if(s) displaymm(0, 8, 8+fs*11, 2, vid.fsize, its(s), 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
|
@ -673,8 +673,9 @@ void wandering() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateSnake(cell *c, int i) {
|
void generateSnake(cell *c, int i, int color) {
|
||||||
c->monst = moHexSnake;
|
c->monst = moHexSnake;
|
||||||
|
c->hitpoints = color;
|
||||||
int cpair = (1<<pattern_threecolor(c)) | (1<<pattern_threecolor(c->mov[i]));
|
int cpair = (1<<pattern_threecolor(c)) | (1<<pattern_threecolor(c->mov[i]));
|
||||||
preventbarriers(c);
|
preventbarriers(c);
|
||||||
int len = nonbitrunc ? 2 : ROCKSNAKELENGTH;
|
int len = nonbitrunc ? 2 : ROCKSNAKELENGTH;
|
||||||
@ -689,7 +690,7 @@ void generateSnake(cell *c, int i) {
|
|||||||
cell *c3 = c2->mov[i];
|
cell *c3 = c2->mov[i];
|
||||||
if(c3->monst || c3->bardir != NODIR || c3->wall) break;
|
if(c3->monst || c3->bardir != NODIR || c3->wall) break;
|
||||||
c2 = c3;
|
c2 = c3;
|
||||||
c2->monst = moHexSnakeTail;
|
c2->monst = moHexSnakeTail; c2->hitpoints = color;
|
||||||
i = (j + (c2->type%4 == 0 ? c2->type/2 : (len%2 ? 2 : c2->type - 2))) % c2->type;
|
i = (j + (c2->type%4 == 0 ? c2->type/2 : (len%2 ? 2 : c2->type - 2))) % c2->type;
|
||||||
createMov(c2, i);
|
createMov(c2, i);
|
||||||
if(!inpair(c2->mov[i], cpair)) {
|
if(!inpair(c2->mov[i], cpair)) {
|
||||||
|
26
orbs.cpp
26
orbs.cpp
@ -577,7 +577,7 @@ void jumpTo(cell *dest, eItem byWhat, int bonuskill, eMonster dashmon) {
|
|||||||
killFriendlyIvy();
|
killFriendlyIvy();
|
||||||
|
|
||||||
cell *c1 = cwt.c;
|
cell *c1 = cwt.c;
|
||||||
animateMovement(cwt.c, dest, LAYER_SMALL);
|
animateMovement(cwt.c, dest, LAYER_SMALL, NOHINT);
|
||||||
cwt.c = dest;
|
cwt.c = dest;
|
||||||
forCellIdEx(c2, i, dest) if(c2->cpdist < dest->cpdist) {
|
forCellIdEx(c2, i, dest) if(c2->cpdist < dest->cpdist) {
|
||||||
cwt.spin = i;
|
cwt.spin = i;
|
||||||
@ -619,13 +619,13 @@ void jumpTo(cell *dest, eItem byWhat, int bonuskill, eMonster dashmon) {
|
|||||||
monstersTurn();
|
monstersTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void growIvyTo(cell *dest, cell *src) {
|
void growIvyTo(cell *dest, cell *src, int direction_hint) {
|
||||||
if(dest->monst)
|
if(dest->monst)
|
||||||
attackMonster(dest, AF_NORMAL | AF_MSG, moFriendlyIvy);
|
attackMonster(dest, AF_NORMAL | AF_MSG, moFriendlyIvy);
|
||||||
else {
|
else {
|
||||||
dest->monst = moFriendlyIvy;
|
dest->monst = moFriendlyIvy;
|
||||||
dest->mondir = neighborId(dest, src);
|
dest->mondir = neighborId(dest, src);
|
||||||
moveEffect(dest, src, moFriendlyIvy);
|
moveEffect(dest, src, moFriendlyIvy, direction_hint);
|
||||||
empathyMove(src, dest, neighborId(src, dest));
|
empathyMove(src, dest, neighborId(src, dest));
|
||||||
}
|
}
|
||||||
createNoise(1);
|
createNoise(1);
|
||||||
@ -797,7 +797,7 @@ void summonAt(cell *dest) {
|
|||||||
if(dest->monst == moTortoise)
|
if(dest->monst == moTortoise)
|
||||||
tortoise::emap[dest] = dest;
|
tortoise::emap[dest] = dest;
|
||||||
addMessage(XLAT("You summon %the1!", dest->monst));
|
addMessage(XLAT("You summon %the1!", dest->monst));
|
||||||
moveEffect(dest, dest, dest->monst);
|
moveEffect(dest, dest, dest->monst, -1);
|
||||||
if(dest->wall == waClosePlate || dest->wall == waOpenPlate)
|
if(dest->wall == waClosePlate || dest->wall == waOpenPlate)
|
||||||
toggleGates(dest, dest->wall);
|
toggleGates(dest, dest->wall);
|
||||||
|
|
||||||
@ -865,7 +865,7 @@ void gun_attack(cell *dest) {
|
|||||||
|
|
||||||
void checkStunKill(cell *dest) {
|
void checkStunKill(cell *dest) {
|
||||||
if(isBird(dest->monst)) {
|
if(isBird(dest->monst)) {
|
||||||
moveEffect(dest, dest, moDeadBird);
|
moveEffect(dest, dest, moDeadBird, NOHINT);
|
||||||
doesFall(dest);
|
doesFall(dest);
|
||||||
if(isWatery(dest) || dest->wall == waChasm || isFire(dest)) {
|
if(isWatery(dest) || dest->wall == waChasm || isFire(dest)) {
|
||||||
addMessage(XLAT("%The1 falls!", dest->monst));
|
addMessage(XLAT("%The1 falls!", dest->monst));
|
||||||
@ -925,10 +925,10 @@ void placeIllusion(cell *c) {
|
|||||||
checkmoveO();
|
checkmoveO();
|
||||||
}
|
}
|
||||||
|
|
||||||
void blowoff(cell *cf, cell *ct) {
|
void blowoff(cell *cf, cell *ct, int direction_hint) {
|
||||||
playSound(ct, "orb-ranged");
|
playSound(ct, "orb-ranged");
|
||||||
addMessage(XLAT("You blow %the1 away!", cf->monst));
|
addMessage(XLAT("You blow %the1 away!", cf->monst));
|
||||||
pushMonster(ct, cf);
|
pushMonster(ct, cf, direction_hint);
|
||||||
if(cf->item == itBabyTortoise && !ct->item)
|
if(cf->item == itBabyTortoise && !ct->item)
|
||||||
moveItem(cf, ct, true);
|
moveItem(cf, ct, true);
|
||||||
items[itOrbAir]--;
|
items[itOrbAir]--;
|
||||||
@ -1024,9 +1024,10 @@ eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
for(; d<c->type; d++) if(c->mov[d] && c->mov[d]->cpdist < c->cpdist) break;
|
for(; d<c->type; d++) if(c->mov[d] && c->mov[d]->cpdist < c->cpdist) break;
|
||||||
if(d<c->type) for(int e=d; e<d+c->type; e++) {
|
if(d<c->type) for(int e=d; e<d+c->type; e++) {
|
||||||
nowhereToBlow = true;
|
nowhereToBlow = true;
|
||||||
cell *c2 = c->mov[e % c->type];
|
int di = e % c->type;
|
||||||
|
cell *c2 = c->mov[di];
|
||||||
if(c2 && c2->cpdist > c->cpdist && passable(c2, c, P_BLOW)) {
|
if(c2 && c2->cpdist > c->cpdist && passable(c2, c, P_BLOW)) {
|
||||||
if(!isCheck(a)) blowoff(c, c2);
|
if(!isCheck(a)) blowoff(c, c2, di);
|
||||||
return itOrbAir;
|
return itOrbAir;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1035,8 +1036,9 @@ eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
// nature
|
// nature
|
||||||
if(items[itOrbNature] && numplayers() == 1 && c->monst != moFriendlyIvy) {
|
if(items[itOrbNature] && numplayers() == 1 && c->monst != moFriendlyIvy) {
|
||||||
cell *sides[8];
|
cell *sides[8];
|
||||||
|
int dirs[8];
|
||||||
int qsides = 0;
|
int qsides = 0;
|
||||||
forCellCM(cf, c)
|
forCellIdCM(cf, d, c)
|
||||||
if(cf->monst == moFriendlyIvy) {
|
if(cf->monst == moFriendlyIvy) {
|
||||||
|
|
||||||
if(c->monst) {
|
if(c->monst) {
|
||||||
@ -1048,11 +1050,13 @@ eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
if(strictlyAgainstGravity(c, cf, false, MF_IVY)) continue;
|
if(strictlyAgainstGravity(c, cf, false, MF_IVY)) continue;
|
||||||
if(monstersnear(cwt.c, NULL, moPlayer, c, cwt.c)) continue;
|
if(monstersnear(cwt.c, NULL, moPlayer, c, cwt.c)) continue;
|
||||||
}
|
}
|
||||||
|
dirs[qsides] = d;
|
||||||
sides[qsides++] = cf;
|
sides[qsides++] = cf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(qsides > 0) {
|
if(qsides > 0) {
|
||||||
if(!isCheck(a)) growIvyTo(c, sides[hrand(qsides)]);
|
int di = hrand(qsides);
|
||||||
|
if(!isCheck(a)) growIvyTo(c, sides[di], revhint(c, dirs[di]));
|
||||||
return itOrbNature;
|
return itOrbNature;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -767,7 +767,7 @@ namespace patterns {
|
|||||||
if((gp::on? (S3==3) : !weirdhyperbolic) && isWarped(c))
|
if((gp::on? (S3==3) : !weirdhyperbolic) && isWarped(c))
|
||||||
val_warped(c, si);
|
val_warped(c, si);
|
||||||
else {
|
else {
|
||||||
si.id = ishept(c) ? 1 : 0;
|
si.id = pseudohept(c) ? 1 : 0;
|
||||||
if(euclid) {
|
if(euclid) {
|
||||||
si.dir = ishex1(c) ? 0 : 3;
|
si.dir = ishex1(c) ? 0 : 3;
|
||||||
if(ctof(c)) si.symmetries = 3;
|
if(ctof(c)) si.symmetries = 3;
|
||||||
@ -956,6 +956,12 @@ namespace patterns {
|
|||||||
else if(a457 && pat == PAT_ZEBRA) {
|
else if(a457 && pat == PAT_ZEBRA) {
|
||||||
val_all(c, si, sub, pat);
|
val_all(c, si, sub, pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(gp::on) {
|
||||||
|
bool football = (pat == PAT_COLORING && (sub & SPF_FOOTBALL)) || pat == 0;
|
||||||
|
if(football) val_nopattern(c, si, sub);
|
||||||
|
else val_threecolors(c, si, sub);
|
||||||
|
}
|
||||||
|
|
||||||
else if(pat == PAT_COLORING && (S7 == 4 || euclid || (a38 && gp_threecolor() == 1))) {
|
else if(pat == PAT_COLORING && (S7 == 4 || euclid || (a38 && gp_threecolor() == 1))) {
|
||||||
val_threecolors(c, si, sub);
|
val_threecolors(c, si, sub);
|
||||||
@ -1626,6 +1632,7 @@ namespace patterns {
|
|||||||
dialog::addBoolItem(s, geometry == g.geo && nonbitrunc == g.nonbitru && whichPattern == g.whichPattern && subpattern_flags == g.subpattern_flags, 'a'+j);
|
dialog::addBoolItem(s, geometry == g.geo && nonbitrunc == g.nonbitru && whichPattern == g.whichPattern && subpattern_flags == g.subpattern_flags, 'a'+j);
|
||||||
}
|
}
|
||||||
bool have_goldberg = S3 == 3 && among(cgroup, cpFootball, cpThree) && !euclid;
|
bool have_goldberg = S3 == 3 && among(cgroup, cpFootball, cpThree) && !euclid;
|
||||||
|
if(!(S7&1) && !nonbitrunc) have_goldberg = false; // always start from non-bitruncated
|
||||||
if(have_goldberg) {
|
if(have_goldberg) {
|
||||||
dialog::addBoolItem(XLAT("Goldberg"), gp::on, 'G');
|
dialog::addBoolItem(XLAT("Goldberg"), gp::on, 'G');
|
||||||
dialog::lastItem().value = gp::operation_name();
|
dialog::lastItem().value = gp::operation_name();
|
||||||
|
@ -334,7 +334,7 @@ void bantar_frame() {
|
|||||||
|
|
||||||
View = Id;
|
View = Id;
|
||||||
|
|
||||||
transmatrix tView = actualV(cth(xcw), Id) * shmup::calc_relative_matrix(cwt.c, xcw.c) * inverse(actualV(cth(cwt), Id));
|
transmatrix tView = actualV(cth(xcw), Id) * shmup::calc_relative_matrix(cwt.c, xcw.c, NOHINT) * inverse(actualV(cth(cwt), Id));
|
||||||
|
|
||||||
if(tphase < 2) part = 0;
|
if(tphase < 2) part = 0;
|
||||||
else if(tphase == 2)
|
else if(tphase == 2)
|
||||||
|
84
shmup.cpp
84
shmup.cpp
@ -1624,7 +1624,7 @@ void movePlayer(monster *m, int delta) {
|
|||||||
m->base->wall = waChasm;
|
m->base->wall = waChasm;
|
||||||
else {
|
else {
|
||||||
m->base->wall = waBigStatue;
|
m->base->wall = waBigStatue;
|
||||||
animateMovement(c2, m->base, LAYER_BOAT);
|
animateMovement(c2, m->base, LAYER_BOAT, NOHINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(m->inBoat && !isWateryOrBoat(c2) && passable(c2, m->base, P_ISPLAYER | P_MIRROR | reflectflag)) {
|
else if(m->inBoat && !isWateryOrBoat(c2) && passable(c2, m->base, P_ISPLAYER | P_MIRROR | reflectflag)) {
|
||||||
@ -2728,7 +2728,7 @@ void moveMonster(monster *m, int delta) {
|
|||||||
m->base->wall = waChasm;
|
m->base->wall = waChasm;
|
||||||
else
|
else
|
||||||
m->base->wall = waBigStatue;
|
m->base->wall = waBigStatue;
|
||||||
animateMovement(c2, m->base, LAYER_BOAT);
|
animateMovement(c2, m->base, LAYER_BOAT, NOHINT);
|
||||||
}
|
}
|
||||||
if(passable_for(m->type, c2, m->base, P_CHAIN | P_ONPLAYER | reflectflag) && !isWatery(c2) && m->inBoat) {
|
if(passable_for(m->type, c2, m->base, P_CHAIN | P_ONPLAYER | reflectflag) && !isWatery(c2) && m->inBoat) {
|
||||||
if(isWatery(m->base))
|
if(isWatery(m->base))
|
||||||
@ -3336,7 +3336,7 @@ transmatrix master_relative(cell *c, bool get_inverse) {
|
|||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!nonbitrunc) {
|
else if(!nonbitrunc && !euclid) {
|
||||||
for(int d=0; d<S7; d++) if(c->master->c7->mov[d] == c)
|
for(int d=0; d<S7; d++) if(c->master->c7->mov[d] == c)
|
||||||
return (get_inverse?invhexmove:hexmove)[d];
|
return (get_inverse?invhexmove:hexmove)[d];
|
||||||
return Id;
|
return Id;
|
||||||
@ -3345,7 +3345,8 @@ transmatrix master_relative(cell *c, bool get_inverse) {
|
|||||||
return pispin * Id;
|
return pispin * Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
transmatrix calc_relative_matrix(cell *c2, cell *c1) {
|
// target, source, direction from source to target
|
||||||
|
transmatrix calc_relative_matrix(cell *c2, cell *c1, int direction_hint) {
|
||||||
|
|
||||||
if(sphere) {
|
if(sphere) {
|
||||||
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
|
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
|
||||||
@ -3358,14 +3359,46 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1) {
|
|||||||
swap(gmatrix, gmatrix0);
|
swap(gmatrix, gmatrix0);
|
||||||
gp::draw_li = bak;
|
gp::draw_li = bak;
|
||||||
}
|
}
|
||||||
if(gmatrix0.count(c2) && gmatrix0.count(c1))
|
if(gmatrix0.count(c2) && gmatrix0.count(c1)) {
|
||||||
return inverse(gmatrix0[c1]) * gmatrix0[c2];
|
transmatrix T = inverse(gmatrix0[c1]) * gmatrix0[c2];
|
||||||
|
if(elliptic && T[2][2] < 0)
|
||||||
|
T = centralsym * T;
|
||||||
|
return T;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
printf("error: gmatrix0 not known\n");
|
printf("error: gmatrix0 not known\n");
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(torus) {
|
||||||
|
transmatrix t = Id;
|
||||||
|
if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));
|
||||||
|
int mirrors = 0;
|
||||||
|
approach:
|
||||||
|
int d = celldistance(c2, c1);
|
||||||
|
forCellIdEx(c3, i, c2) {
|
||||||
|
if(celldistance(c3, c1) < d) {
|
||||||
|
if(whateveri) printf(" %d [%p,%d]", i, c3, celldistance(c3, c1));
|
||||||
|
if(c2->type < 8)
|
||||||
|
t = eumovedir(i+(euclid6?3:2)) * t;
|
||||||
|
else if(i&1)
|
||||||
|
t = eumovedir(2+i/2) * eumovedir(2+(i+1)/2) * t;
|
||||||
|
else
|
||||||
|
t = eumovedir(2+i/2) * t;
|
||||||
|
if(c2->mirror(i)) mirrors++;
|
||||||
|
c2 = c3;
|
||||||
|
goto approach;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(d != 0) printf("ERROR not reached\n");
|
||||||
|
if(mirrors&1) t = Mirror * t * Mirror;
|
||||||
|
if(whateveri) printf(" => %p\n", c1);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(euclid) return inverse(gmatrix0[c1]) * gmatrix0[c2];
|
||||||
|
|
||||||
heptagon *h1 = c1->master;
|
heptagon *h1 = c1->master;
|
||||||
transmatrix gm = master_relative(c1, true);
|
transmatrix gm = master_relative(c1, true);
|
||||||
heptagon *h2 = c2->master;
|
heptagon *h2 = c2->master;
|
||||||
@ -3375,20 +3408,26 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1) {
|
|||||||
//bool hsol = false;
|
//bool hsol = false;
|
||||||
//transmatrix sol;
|
//transmatrix sol;
|
||||||
while(h1 != h2) {
|
while(h1 != h2) {
|
||||||
int confusion = 0;
|
if(quotient == 1) {
|
||||||
if(quotient == 1 && gp::on) {
|
transmatrix T;
|
||||||
for(int d=0; d<S7; d++) if(h2->move[d] == h1) confusion++;
|
hyperpoint hint = ddspin(c1, direction_hint) * xpush(1e-2) * C0;
|
||||||
if(confusion > 1) {
|
ld bestdist = 1e9;
|
||||||
transmatrix T;
|
for(int d=0; d<S7; d++) if(h2->move[d]) {
|
||||||
confusion = 0;
|
int sp = h2->spin(d);
|
||||||
for(int d=0; d<S7; d++) if(h2->move[d] == h1) {
|
transmatrix S = heptmove[sp] * spin(2*M_PI*d/S7);
|
||||||
int sp = h2->spin(d);
|
if(h2->move[d] == h1) {
|
||||||
transmatrix T1 = gm * heptmove[sp] * spin(2*M_PI*d/S7) * where;
|
transmatrix T1 = gm * S * where;
|
||||||
if(confusion == 0 || T1[2][2] < T[2][2]) T = T1;
|
auto curdist = hdist(tC0(T1), hint);
|
||||||
confusion++;
|
if(curdist < bestdist) T = T1, bestdist = curdist;
|
||||||
|
}
|
||||||
|
for(int e=0; e<S7; e++) if(h2->move[d]->move[e] == h1) {
|
||||||
|
int sp2 = h2->move[d]->spin(e);
|
||||||
|
transmatrix T1 = gm * heptmove[sp2] * spin(2*M_PI*e/S7) * S * where;
|
||||||
|
auto curdist = hdist(tC0(T1), hint);
|
||||||
|
if(curdist < bestdist) T = T1, bestdist = curdist;
|
||||||
}
|
}
|
||||||
return T;
|
|
||||||
}
|
}
|
||||||
|
return T;
|
||||||
}
|
}
|
||||||
for(int d=0; d<S7; d++) if(h2->move[d] == h1) {
|
for(int d=0; d<S7; d++) if(h2->move[d] == h1) {
|
||||||
int sp = h2->spin(d);
|
int sp = h2->spin(d);
|
||||||
@ -3421,17 +3460,14 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1) {
|
|||||||
transmatrix &ggmatrix(cell *c) {
|
transmatrix &ggmatrix(cell *c) {
|
||||||
transmatrix& t = gmatrix[c];
|
transmatrix& t = gmatrix[c];
|
||||||
if(t[2][2] == 0) {
|
if(t[2][2] == 0) {
|
||||||
if(torus) {
|
if(torus && centerover.c)
|
||||||
forCellIdEx(c2, i, c)
|
t = calc_relative_matrix(c, centerover.c, NOHINT);
|
||||||
if(celldistance(c2, centerover.c) < celldistance(c, centerover.c))
|
|
||||||
t = ggmatrix(c2) * eumovedir(3+i);
|
|
||||||
}
|
|
||||||
else if(euclid) {
|
else if(euclid) {
|
||||||
if(!centerover.c) centerover = cwt;
|
if(!centerover.c) centerover = cwt;
|
||||||
t = View * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
|
t = View * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h->c7);
|
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h->c7, NOHINT);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -1269,6 +1269,7 @@ void fillpixel(int x, int y, unsigned col) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void texture_data::undo() {
|
void texture_data::undo() {
|
||||||
|
texture::config.data.pixels_to_draw.clear();
|
||||||
while(!undos.empty()) {
|
while(!undos.empty()) {
|
||||||
auto p = undos.back();
|
auto p = undos.back();
|
||||||
undos.pop_back();
|
undos.pop_back();
|
||||||
|
Loading…
Reference in New Issue
Block a user