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

improved mirrors in various geometries

This commit is contained in:
Zeno Rogue 2018-08-21 15:37:59 +02:00
parent ae19323e00
commit 7cdf1a353f
8 changed files with 136 additions and 31 deletions

View File

@ -1056,6 +1056,33 @@ namespace whirlpool {
namespace mirror { namespace mirror {
bool build(cell *c) {
if(gp::on) {
if(c == c->master->c7) {
c->wall = ((gp::param.second == 0 || gp::param.first == gp::param.second) && hrand(2)) ? waMirror : waCloud;
return true;
}
return false;
}
if(archimedean) {
c->wall = hrand(2) ? waMirror : waCloud;
return true;
}
if(binarytiling || irr::on) {
// mirrors not supported
if(is_mirrorland(c)) {
c->item = itShard;
return true;
}
return false;
}
if(nonbitrunc?pseudohept(c):!ishept(c)) {
c->wall = hrand(2) ? waMirror : waCloud;
return true;
}
return false;
}
vector<pair<int, cellwalker>> mirrors; vector<pair<int, cellwalker>> mirrors;
static const int LIGHTNING = -1; // passed instead of cpid static const int LIGHTNING = -1; // passed instead of cpid
@ -1111,10 +1138,59 @@ namespace mirror {
} }
} }
// we go by heptagons in Archimedean,
bool equal(heptspin h1, heptspin h2, int lev) {
if(h1.at->degree() != h2.at->degree()) return false;
if(lev) for(int i=0; i<h1.at->degree(); i++) {
heptspin h11 = h1 + i + wstep;
heptspin h21 = h2 + i + wstep;
if(!equal(h11, h21, lev-1)) return false;
}
return true;
}
int create_archimedean_rec(heptspin hs, int cpid, heptspin hs0, int lev) {
int result = 0;
for(int i=0; i<hs.at->degree(); i++) {
heptspin hs1 = hs + i;
if(lev == 0) {
if(hs1.at != hs0.at && equal(hs1, hs0, 3)) {
createMirror(cellwalker(hs1.at->c7, hs1.spin, hs1.mirrored), cpid);
result++;
}
}
else result += create_archimedean_rec(hs1 + wstep, cpid, hs0, lev-1);
}
return result;
}
void create_archimedean(cellwalker cw, int cpid, bool mirrored) {
heptspin hs(cw.at->master, cw.spin, cw.mirrored);
heptspin hsx = hs;
if(mirrored) hsx += wmirror;
if(create_archimedean_rec(hsx, cpid, hs, 2)) return;
if(create_archimedean_rec(hsx, cpid, hs, 3)) return;
if(create_archimedean_rec(hsx, cpid, hs, 4)) return;
}
void createMirrors(cellwalker cw, int cpid) { void createMirrors(cellwalker cw, int cpid) {
if(archimedean) {
create_archimedean(cw, cpid, true);
return;
}
cw.mirrored = !cw.mirrored; cw.mirrored = !cw.mirrored;
cell *c = cw.at; cell *c = cw.at;
if(gp::on) {
for(int i=0; i<cw.at->type; i++) {
heptspin hs(cw.at->master, cw.spin, cw.mirrored);
hs = hs + i + wstep + i - (gp::param.first == gp::param.second ? 1 : 0);
createMirror(cellwalker(hs.at->c7, hs.spin, hs.mirrored), cpid);
}
return;
}
for(int i=0; i<cw.at->type; i++) { for(int i=0; i<cw.at->type; i++) {
auto cws = cw + wstep; auto cws = cw + wstep;
if(cws.at->type == c->type) if(cws.at->type == c->type)
@ -1124,9 +1200,39 @@ namespace mirror {
} }
void createMirages(cellwalker cw, int cpid) { void createMirages(cellwalker cw, int cpid) {
if(nonbitrunc) { if(archimedean) {
create_archimedean(cw, cpid, false);
return;
}
if(gp::on && !(S7 & 1)) {
for(int i=0; i<cw.at->type; i++) {
heptspin hs(cw.at->master, cw.spin, cw.mirrored);
hs = hs + i + wstep + 1 + wstep + 1 + (S7/2) - i + 1;
createMirror(cellwalker(hs.at->c7, hs.spin, hs.mirrored), cpid);
}
return;
}
if(gp::on && (S7 & 1)) {
for(int i=0; i<cw.at->type; i++) {
heptspin hs(cw.at->master, cw.spin, cw.mirrored);
hs = hs + i + wstep + (S7/2) + wstep - 2 + wstep + (S7/2) - i;
createMirror(cellwalker(hs.at->c7, hs.spin, hs.mirrored), cpid);
}
return;
}
if(nonbitrunc && !(S7 & 1)) {
for(int i=0; i<cw.at->type; i++) for(int i=0; i<cw.at->type; i++)
createMirror(cw + i + wstep + 3 + wstep + 5 + wstep + 3 - i, cpid); createMirror(cw + i + wstep + 1 + wstep + 1 + (S7/2) - i, cpid);
return;
}
if(nonbitrunc && (S7 & 1) && (S3 == 4)) {
for(int i=0; i<cw.at->type; i++)
createMirror(cw + i + wstep + 1 + wstep - (S7/2) + wstep - (S7/2) - i, cpid);
return;
}
if(nonbitrunc && (S7 & 1)) {
for(int i=0; i<cw.at->type; i++)
createMirror(cw + i + wstep + (S7/2) + wstep - 2 + wstep + (S7/2) - i, cpid);
return; return;
} }
for(int i=0; i<S6; i++) { for(int i=0; i<S6; i++) {

View File

@ -752,4 +752,8 @@ bool isTechnicalLand(eLand l) {
l == laMirrorWall2 || l == laMercuryRiver || l == laMemory; l == laMirrorWall2 || l == laMercuryRiver || l == laMemory;
} }
bool is_mirrorland(cell *c) {
return among(c->land, laMirror, laMirrorOld);
}
} }

View File

@ -3320,7 +3320,7 @@ string itemcounter(int qty) {
void gainShard(cell *c2, const char *msg) { void gainShard(cell *c2, const char *msg) {
invismove = false; invismove = false;
string s = XLAT(msg); string s = XLAT(msg);
if(among(c2->land, laMirror, laMirrorOld) && !peace::on) { if(is_mirrorland(c2) && !peace::on) {
gainItem(itShard); gainItem(itShard);
s += itemcounter(items[itShard]); s += itemcounter(items[itShard]);
collectMessage(c2, itShard); collectMessage(c2, itShard);

View File

@ -2052,24 +2052,24 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
if(d>=4) cw += 2; if(d>=4) cw += 2;
transmatrix Vs = Vparam; transmatrix Vs = Vparam;
bool mirr = cw.mirrored; bool mirr = cw.mirrored;
Vs = Vs * ddspin(c, cw.spin-cwt.spin, masterless ? 0 : M_PI); transmatrix T = Id;
nospins = applyAnimation(cwt.at, Vs, footphase, LAYER_SMALL); nospins = applyAnimation(cwt.at, T, footphase, LAYER_SMALL);
if(!nospins) Vs = Vs * ddspin(c, cwt.spin); if(nospins)
Vs = Vs * ddspin(c, cw.spin, 0) * iddspin(cwt.at, cwt.spin, 0) * T;
else
Vs = Vs * ddspin(c, cw.spin, 0);
if(mirr) Vs = Vs * Mirror; if(mirr) Vs = Vs * Mirror;
if(inmirrorcount&1) mirr = !mirr; if(inmirrorcount&1) mirr = !mirr;
col = mirrorcolor(geometry == gElliptic ? det(Vs) < 0 : mirr); col = mirrorcolor(geometry == gElliptic ? det(Vs) < 0 : mirr);
if(!mouseout() && !nospins) {
hyperpoint P2 = Vs * inverse(cwtV) * mouseh;
queuechr(P2, 10, 'x', 0xFF00);
}
if(!nospins && flipplayer) Vs = Vs * pispin; if(!nospins && flipplayer) Vs = Vs * pispin;
if(mmmon) { if(mmmon) {
drawMonsterType(moMimic, c, Vs, col, footphase); drawMonsterType(moMimic, c, Vs, col, footphase);
drawPlayerEffects(Vs, c, false); drawPlayerEffects(Vs, c, false);
} }
if(!mouseout() && !nospins) {
transmatrix invxy = Id;
if(flipplayer) invxy[0][0] = invxy[1][1] = -1;
hyperpoint P2 = Vs * inverse(cwtV) * invxy * mouseh;
queuechr(P2, 10, 'x', 0xFF00);
}
} }
return !mmmon; return !mmmon;
} }

View File

@ -533,8 +533,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
itOrbFlash, itOrbSpeed, itOrbFire, itOrbWinter, itOrbAether, itOrbLife}; itOrbFlash, itOrbSpeed, itOrbFire, itOrbWinter, itOrbAether, itOrbLife};
c->item = powerorbs[hrand(6)]; c->item = powerorbs[hrand(6)];
} }
else if(!ctof(c) && hrand(5000) < 10) else if(hrand(5000) < 10 && mirror::build(c)) ;
c->wall = hrand(2) ? waMirror : waCloud;
else if(hrand(1000) < 10 + (items[itPower] ? 10:0) + (items[itPower] + yendor::hardness())) else if(hrand(1000) < 10 + (items[itPower] ? 10:0) + (items[itPower] + yendor::hardness()))
c->monst = eMonster(moWitch + hrand(NUMWITCH)); c->monst = eMonster(moWitch + hrand(NUMWITCH));
} }
@ -1993,8 +1992,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
case laMirrorOld: case laMirrorOld:
ONEMPTY { ONEMPTY {
if((nonbitrunc?pseudohept(c):!ishept(c)) && hrand(5000) < 120 && (peace::on || notDippingFor(itShard))) if(hrand(5000) < 120 && (peace::on || notDippingFor(itShard)) && mirror::build(c));
c->wall = hrand(2) ? waMirror : waCloud;
else if(ishept(c) && hrand(5000) < 10 * PRIZEMUL) else if(ishept(c) && hrand(5000) < 10 * PRIZEMUL)
placePrizeOrb(c); placePrizeOrb(c);
else if(hrand(12000) < 8 + items[itShard] + yendor::hardness()) else if(hrand(12000) < 8 + items[itShard] + yendor::hardness())
@ -2006,8 +2004,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
case laMirror: case laMirror:
ONEMPTY { ONEMPTY {
if((nonbitrunc?pseudohept(c):!ishept(c)) && hrand(1250) < 120 && (peace::on || notDippingFor(itShard))) if(hrand(1250) < 120 && (peace::on || notDippingFor(itShard)) && mirror::build(c)) ;
c->wall = hrand(2) ? waMirror : waCloud;
else if(ishept(c) && hrand(5000) < 10 * PRIZEMUL) else if(ishept(c) && hrand(5000) < 10 * PRIZEMUL)
placePrizeOrb(c); placePrizeOrb(c);
else if(hrand(cwt.at->land == laMirror ? 600 : 2400) < 8 + items[itShard] + yendor::hardness()) { else if(hrand(cwt.at->land == laMirror ? 600 : 2400) < 8 + items[itShard] + yendor::hardness()) {
@ -2205,12 +2202,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
ONEMPTY { ONEMPTY {
if(nonbitrunc && c->land == laCrossroads5 && hrand(100) < 60) if(nonbitrunc && c->land == laCrossroads5 && hrand(100) < 60)
c->wall = waBarrier; c->wall = waBarrier;
else if(!ctof(c) && !inv::on && items[itShard] >= 10 && hrand(8000) < 120*orbcrossfun(items[itShard]) && !gp::on) else if(!inv::on && items[itShard] >= 10 && hrand(8000) < 120*orbcrossfun(items[itShard]) && mirror::build(c)) ;
c->wall = hrand(2) ? waMirror : waCloud; else if(hyperstonesUnlocked() && hrand(8000) < 100 && mirror::build(c)) ;
else if(!ctof(c) && hyperstonesUnlocked() && hrand(8000) < 100 && !gp::on) else if(tactic::on && isCrossroads(specialland) && hrand(8000) < 120 && mirror::build(c)) ;
c->wall = hrand(2) ? waMirror : waCloud;
else if(!ctof(c) && tactic::on && isCrossroads(specialland) && hrand(8000) < 120 && !gp::on)
c->wall = hrand(2) ? waMirror : waCloud;
else if(c->land == laCrossroads4 && hrand(24000) < 10 && tactic::on) else if(c->land == laCrossroads4 && hrand(24000) < 10 && tactic::on)
c->wall = waRose; c->wall = waRose;
else { else {

View File

@ -1138,7 +1138,10 @@ land_validity_t& land_validity(eLand l) {
return not_enough_space; return not_enough_space;
// mirrors do not work in gp // mirrors do not work in gp
if(among(l, laMirror, laMirrorOld) && gp::on) if(among(l, laMirror, laMirrorOld) && (gp::on && old_daily_id < 33))
return dont_work;
if(binarytiling && among(l, laMirror, laMirrorOld))
return dont_work; return dont_work;
if(l == laWhirlwind && hyperbolic_not37) if(l == laWhirlwind && hyperbolic_not37)

View File

@ -354,7 +354,8 @@ void wandering() {
placeLocalOrbs(c); placeLocalOrbs(c);
if(!c->item) c->item = wanderingTreasure(c); if(!c->item) c->item = wanderingTreasure(c);
if(c->item == itShard) { if(c->item == itShard) {
c->item = itNone, c->wall = hrand(2) ? waMirror : waCloud; c->item = itNone;
mirror::build(c);
} }
if(c->item == itFulgurite) { if(c->item == itFulgurite) {
c->item = itNone, c->wall = waSandstone; c->item = itNone, c->wall = waSandstone;

View File

@ -369,13 +369,10 @@ ld orbcrossfun(int tr) {
bool buildPrizeMirror(cell *c, int freq) { bool buildPrizeMirror(cell *c, int freq) {
if(inv::on) return false; if(inv::on) return false;
if(gp::on) return false;
if(c->type == 7 && !nonbitrunc) return false;
if(items[itShard] < 25) return false; if(items[itShard] < 25) return false;
if(freq && hrand(freq * 100 / orbprizefun(items[itShard])) >= 100) if(freq && hrand(freq * 100 / orbprizefun(items[itShard])) >= 100)
return false; return false;
c->wall = hrand(2) ? waCloud : waMirror; return mirror::build(c);
return true;
} }
eLand getPrizeLand(cell *c = cwt.at) { eLand getPrizeLand(cell *c = cwt.at) {