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 {
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;
static const int LIGHTNING = -1; // passed instead of cpid
@ -1110,11 +1137,60 @@ namespace mirror {
mirrors.emplace_back(cpid, cw);
}
}
// 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) {
if(archimedean) {
create_archimedean(cw, cpid, true);
return;
}
cw.mirrored = !cw.mirrored;
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++) {
auto cws = cw + wstep;
if(cws.at->type == c->type)
@ -1124,9 +1200,39 @@ namespace mirror {
}
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++)
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;
}
for(int i=0; i<S6; i++) {

View File

@ -752,4 +752,8 @@ bool isTechnicalLand(eLand l) {
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) {
invismove = false;
string s = XLAT(msg);
if(among(c2->land, laMirror, laMirrorOld) && !peace::on) {
if(is_mirrorland(c2) && !peace::on) {
gainItem(itShard);
s += itemcounter(items[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;
transmatrix Vs = Vparam;
bool mirr = cw.mirrored;
Vs = Vs * ddspin(c, cw.spin-cwt.spin, masterless ? 0 : M_PI);
nospins = applyAnimation(cwt.at, Vs, footphase, LAYER_SMALL);
if(!nospins) Vs = Vs * ddspin(c, cwt.spin);
transmatrix T = Id;
nospins = applyAnimation(cwt.at, T, footphase, LAYER_SMALL);
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(inmirrorcount&1) mirr = !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(mmmon) {
drawMonsterType(moMimic, c, Vs, col, footphase);
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;
}

View File

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

View File

@ -1138,9 +1138,12 @@ land_validity_t& land_validity(eLand l) {
return not_enough_space;
// 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;
if(l == laWhirlwind && hyperbolic_not37)
return pattern_incompatibility;

View File

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

View File

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