westwall:: initial commit

This commit is contained in:
Zeno Rogue 2018-12-21 14:41:23 +01:00
parent 724d3516fa
commit 6d392ce07e
7 changed files with 117 additions and 24 deletions

View File

@ -664,7 +664,7 @@ cell *randomDown(cell *c) {
}
int edgeDepth(cell *c) {
if(c->land == laIvoryTower || c->land == laEndorian || c->land == laDungeon)
if(c->land == laIvoryTower || c->land == laEndorian || c->land == laDungeon || c->land == laWestWall)
return coastvalEdge(c);
else if(c->land != laBarrier) {
for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->land == laBarrier)

View File

@ -118,5 +118,70 @@ namespace brownian {
}
namespace westwall {
void switchTreasure(cell *c) {
c->item = itNone;
if(safety) return;
if(hrand(5000) < PT(100 + 2 * (kills[moAirElemental] + kills[moWindCrow]), 200) && notDippingFor(itWindstone)
&& getGhostcount() < 2)
c->item = itWest;
else if(hrand(5000) < 20*PRIZEMUL)
placeLocalOrbs(c);
}
cell *where;
int dfrom[2], dto[2], qdirs;
int gdist(int d, int e) { return dirdiff(d-e, where->type); }
void build(vector<cell*>& whirlline, int d) {
again:
cell *at = whirlline[isize(whirlline)-1];
cell *prev = whirlline[isize(whirlline)-2];
for(int i=0; i<at->type; i++)
if(at->move(i) && coastvalEdge(at->move(i)) == d && at->move(i) != prev) {
whirlline.push_back(at->move(i));
goto again;
}
}
void moveAt(cell *c, manual_celllister& cl) {
if(cl.listed(c)) return;
if(c->land != laWestWall) return;
vector<cell*> whirlline;
int d = coastvalEdge(c);
whirlline.push_back(c);
whirlline.push_back(ts::left_of(c, coastvalEdge));
build(whirlline, d);
reverse(whirlline.begin(), whirlline.end());
build(whirlline, d);
int z = isize(whirlline);
for(int i=0; i<z; i++) {
cl.add(whirlline[i]);
if(whirlline[i]->mpdist == BARLEV)
switchTreasure(whirlline[i]);
}
for(int i=0; i<z-1; i++) {
moveItem(whirlline[i], whirlline[i+1], true);
if(whirlline[i]->item)
animateMovement(whirlline[i+1], whirlline[i], LAYER_BOAT, NOHINT);
}
for(int i=0; i<z; i++)
pickupMovedItems(whirlline[i]);
}
void move() {
manual_celllister cl;
for(cell *c: dcal) moveAt(c, cl);
// Keys and Orbs of Yendor always move
using namespace yendor;
for(int i=0; i<isize(yi); i++) {
moveAt(yi[i].path[0], cl);
moveAt(yi[i].path[YDIST-1], cl);
}
}
}
}
#endif

View File

@ -14,15 +14,11 @@ bool isIcyLand(cell *c) {
}
bool isGravityLand(eLand l) {
return
l == laIvoryTower || l == laEndorian ||
l == laMountain || l == laDungeon;
return among(l, laIvoryTower, laEndorian, laMountain, laDungeon, laWestWall);
}
bool isEquidLand(eLand l) {
return
l == laIvoryTower || l == laEndorian || l == laDungeon ||
isHaunted(l) || l == laOcean;
return isHaunted(l) || among(l, laIvoryTower, laEndorian, laDungeon, laOcean, laWestWall);
}
// watery

View File

@ -59,6 +59,7 @@ flagtype havewhat, hadwhat;
#define HF_HEXD Flag(28)
#define HF_ALT Flag(29)
#define HF_MONK Flag(30)
#define HF_WESTWALL Flag(31)
bool seenSevenMines = false;
@ -485,7 +486,7 @@ bool checkflags(flagtype flags, int x) {
bool strictlyAgainstGravity(cell *w, cell *from, bool revdir, flagtype flags) {
return
cellEdgeUnstable(w, flags) && cellEdgeUnstable(from, flags) &&
!(shmup::on && from == w) && gravityLevel(w) != gravityLevel(from) + (revdir?1:-1);
!(shmup::on && from == w) && gravityLevelDiff(w, from) != (revdir?1:-1);
}
bool passable(cell *w, cell *from, flagtype flags) {
@ -2566,6 +2567,19 @@ int gravityLevel(cell *c) {
return 0;
}
int gravityLevelDiff(cell *c, cell *d) {
if(c->land != laWestWall || d->land != laWestWall)
return gravityLevel(c) - gravityLevel(d);
int bonus = 0;
int id = parent_id(c, 1, coastvalEdge);
for(int a=0; a<3; a++)
if(c->modmove(id+a) == d) bonus++;
id = parent_id(c, -1, coastvalEdge);
for(int a=0; a<3; a++)
if(c->modmove(id-a) == d) bonus--;
return bonus;
}
bool canUnstable(eWall w, flagtype flags) {
return w == waNone || w == waCanopy || w == waOpenPlate || w == waClosePlate ||
w == waOpenGate || ((flags & MF_STUNNED) && (w == waLadder || w == waTrunk || w == waSolidBranch || w == waWeakBranch
@ -2574,11 +2588,10 @@ bool canUnstable(eWall w, flagtype flags) {
bool cellEdgeUnstable(cell *c, flagtype flags) {
if(!isGravityLand(c->land) || !canUnstable(c->wall, flags)) return false;
int d = gravityLevel(c);
for(int i=0; i<c->type; i++) if(c->move(i)) {
if(isAnyIvy(c->move(i)->monst) &&
c->land == laMountain && !(flags & MF_IVY)) return false;
if(gravityLevel(c->move(i)) == d-1) {
if(gravityLevelDiff(c, c->move(i)) == 1) {
if(againstWind(c->move(i), c)) return false;
if(!passable(c->move(i), NULL, P_MONSTER | P_DEADLY))
return false;
@ -2828,7 +2841,7 @@ void buildRosemap() {
int getDistLimit() { return base_distlimit; }
bool nogoSlow(cell *to, cell *from) {
if(cellEdgeUnstable(to) && gravityLevel(to) >= gravityLevel(from)) return true;
if(cellEdgeUnstable(to) && gravityLevelDiff(to, from) >= 0) return true;
if(cellUnstable(to)) return true;
return false;
}
@ -3080,6 +3093,7 @@ void bfs() {
if(c2->land == laWhirlpool) havewhat |= HF_WHIRLPOOL;
if(c2->land == laWhirlwind) havewhat |= HF_WHIRLWIND;
if(c2->land == laWestWall) havewhat |= HF_WESTWALL;
if(c2->land == laPrairie) havewhat |= HF_RIVER;
if(c2->wall == waRose) havewhat |= HF_ROSE;
@ -3288,14 +3302,14 @@ void destroyTrapsAround(cell *c) {
void destroyWeakBranch(cell *cf, cell *ct, eMonster who) {
if(cf && ct && cf->wall == waWeakBranch && cellEdgeUnstable(ct) &&
gravityLevel(ct) >= gravityLevel(cf) && !ignoresPlates(who)) {
gravityLevelDiff(ct, cf) >= 0 && !ignoresPlates(who)) {
cf->wall = waCanopy;
if(!cellEdgeUnstable(cf)) { cf->wall = waWeakBranch; return; }
playSound(cf, "trapdoor");
drawParticles(cf, winf[waWeakBranch].color, 4);
}
if(cf && ct && cf->wall == waSmallBush && cellEdgeUnstable(ct) &&
gravityLevel(ct) >= gravityLevel(cf) && !ignoresPlates(who)) {
gravityLevelDiff(ct, cf) >= 0 && !ignoresPlates(who)) {
cf->wall = waNone;
if(!cellEdgeUnstable(cf)) { cf->wall = waSmallBush; return; }
playSound(cf, "trapdoor");
@ -4004,7 +4018,7 @@ int pickDownDirection(cell *c, flagtype mf) {
int downs[MAX_EDGE], qdowns = 0;
int bestdif = -100;
forCellIdEx(c2, i, c) {
if(gravityLevel(c2) < gravityLevel(c) && passable_for(c->monst, c2, c, P_MIRROR) &&
if(gravityLevelDiff(c2, c) < 0 && passable_for(c->monst, c2, c, P_MIRROR) &&
!isPlayerOn(c2)) {
int cdif = i-c->mondir;
if(cdif < 0) cdif += c->type;
@ -4041,12 +4055,12 @@ cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid, int& p
pushdir = (push+wstep).spin;
if(valid(push.at)) return push.at;
}
if(gravityLevel(push.at) < gravityLevel(c2)) {
if(gravityLevelDiff(push.at, c2) < 0) {
push = push + wstep + 1 + wstep;
if(gravityLevel(push.at) < gravityLevel(c2)) {
if(gravityLevelDiff(push.at, c2) < 0) {
push = push + wstep - 2 + wstep;
}
if(gravityLevel(push.at) < gravityLevel(c2)) {
if(gravityLevelDiff(push.at, c2) < 0) {
push = push + wstep + 1 + wstep;
}
pushdir = (push+wstep).spin;
@ -4651,7 +4665,7 @@ void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
if((mf & MF_ONLYEAGLE) && c->monst != moEagle && c->monst != moBat)
return;
// in the gravity lands, eagles cannot ascend in their second move
if((mf & MF_ONLYEAGLE) && gravityLevel(c) < gravityLevel(from)) {
if((mf & MF_ONLYEAGLE) && gravityLevelDiff(c, from) < 0) {
onpath(c, 0);
return;
}
@ -6033,6 +6047,8 @@ void movemonsters() {
if(havewhat & HF_WHIRLPOOL) whirlpool::move();
DEBT("whirlwind");
if(havewhat & HF_WHIRLWIND) whirlwind::move();
DEBT("westwall");
if(havewhat & HF_WESTWALL) westwall::move();
DEBT("river");
if(havewhat & HF_RIVER) prairie::move();
/* DEBT("magnet");

View File

@ -2998,6 +2998,10 @@ void setcolors(cell *c, color_t& wcol, color_t& fcol) {
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
break;
case laWestWall:
fcol = 0x10101 * (32 + (c->landparam&1) * 32) + 0x400000;
break;
case laDungeon: {
int lp = c->landparam % 5;
// xcol = (c->landparam&1) ? 0xD00000 : 0x00D000;
@ -4815,7 +4819,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
if(it) {
if((c->land == laWhirlwind || c->item == itBabyTortoise) && c->wall != waBoat) {
if((c->land == laWhirlwind || c->item == itBabyTortoise || c->land == laWestWall) && c->wall != waBoat) {
double footphase = 0;
Vboat = &(Vboat0 = *Vboat);
applyAnimation(c, Vboat0, footphase, LAYER_BOAT);
@ -4966,7 +4970,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(!euclid) {
bool usethis = false;
double spd = 1;
bool rev = false;
int side = 0;
if(binarytiling && conformal::do_rotate >= 2) {
if(!straightDownSeek || c->master->distance < straightDownSeek->master->distance) {
@ -4976,7 +4980,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
else if(isGravityLand(cwt.at->land) && cwt.at->land != laMountain) {
if(cwt.at->land == laDungeon) rev = true;
if(cwt.at->land == laDungeon) side = 2;
if(cwt.at->land == laWestWall) side = 1;
if(conformal::do_rotate >= 1)
if(!straightDownSeek || edgeDepth(c) < edgeDepth(straightDownSeek)) {
usethis = true;
@ -4995,7 +5000,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(!straightDownSeek || !straightDownSeek->master->alt || celldistAlt(c) < celldistAlt(straightDownSeek)) {
usethis = true;
spd = .5;
if(cwt.at->land == laMountain) rev = true;
if(cwt.at->land == laMountain) side = 2;
}
}
@ -5010,8 +5015,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(usethis) {
straightDownSeek = c;
downspin = atan2(VC0[1], VC0[0]);
downspin -= M_PI/2;
if(rev) downspin += M_PI;
downspin += (side-1) * M_PI/2;
downspin += conformal::rotation * degree;
while(downspin < -M_PI) downspin += 2*M_PI;
while(downspin > +M_PI) downspin -= 2*M_PI;

View File

@ -2083,6 +2083,7 @@ void explosion(cell *c, int power, int central);
void explodeBarrel(cell *c);
int gravityLevel(cell *c);
int gravityLevelDiff(cell *c, cell *f);
void fullcenter();
void movecost(cell* from, cell *to, int phase); // 1 = pre-collect, 2 = post-collect, 3 = both
void checkmove();

View File

@ -1146,6 +1146,17 @@ void giantLandSwitch(cell *c, int d, cell *from) {
}
break;
case laWestWall:
if(d == 9)
westwall::switchTreasure(c);
ONEMPTY {
if(hrand(4500) < items[itWest] + yendor::hardness())
c->monst = moWindCrow;
if(hrand(doCross?3000:30000) < items[itWest] + yendor::hardness() - 5)
c->monst = moAirElemental;
}
break;
case laWhirlwind:
if(d == 9) {
if(S7 == 5)