new land: Docks

This commit is contained in:
Zeno Rogue 2017-12-29 01:10:47 +01:00
parent 7685868fb2
commit 5f5c86e529
15 changed files with 136 additions and 27 deletions

View File

@ -1203,6 +1203,8 @@ itemtype iinf[ittypes] = {
"Does not affect multi-tile monsters."},
{ '!', 0x80FF00, "Glowing Crystal", crystaldesc},
{ '!', 0x80FF80, "Snake Oil", NODESCYET},
{ '*', 0x80FF80, "Dock Treasure", NODESCYET},
{ '*', 0x80FF80, "Invix Treasure", NODESCYET},
};
// --- wall types ---
@ -1380,6 +1382,8 @@ walltype winf[walltypes] = {
{ '^', 0xD00000, "arrow trap", arrowtrapdesc},
{ '=', 0xE2E2E2, "mercury river", "A river of mercury."},
{ '&', 0xD00000, "lava", lavadesc},
{ '=', 0x804000, "dock", "A dock."},
{ '^', 0xFF8000, "burning dock", "A burning dock."},
};
// --- land types ---
@ -1566,6 +1570,8 @@ const landtype linf[landtypes] = {
{ 0xE2725B, "Terracotta Army", terraldesc},
{ 0x80FF00, "Crystal World", crystaldesc},
{ 0x306030, "Snake Nest", NODESCYET},
{ 0x80FF00, "Docks", NODESCYET},
{ 0x306030, "Invisible", NODESCYET},
};
struct landtacinfo { eLand l; int tries, multiplier; };
@ -1597,7 +1603,10 @@ vector<landtacinfo> land_tac = {
{laCrossroads, 10, 1}, {laCrossroads2, 10, 1}, {laCrossroads3, 10, 1}, {laCrossroads4, 10, 1},
{laCamelot, 1, 100},
{laWildWest, 10, 1}
{laWildWest, 10, 1},
{laDual, 10, 1},
{laSnakeNest, 10, 1},
{laDocks, 10, 1}
};
vector<eLand> randlands = {

View File

@ -68,7 +68,7 @@ struct genderswitch_t {
#define NUM_GS 6
static const int ittypes = 123;
static const int ittypes = 125;
struct itemtype {
char glyph;
@ -112,10 +112,11 @@ enum eItem {
itInventory,
itLavaLily, itHunting, itBlizzard, itTerra,
itOrbSide1, itOrbSide2, itOrbSide3,
itOrbLava, itOrbMorph, itGlowCrystal, itSnake
itOrbLava, itOrbMorph, itGlowCrystal, itSnake,
itDock, itInvix
};
static const int walltypes = 105;
static const int walltypes = 107;
struct walltype {
char glyph;
@ -155,10 +156,11 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
waPetrifiedBridge,
waTempBridgeBlocked,
waTerraWarrior, waBubble,
waArrowTrap, waMercury, waMagma
waArrowTrap, waMercury, waMagma,
waDock, waBurningDock
};
static const int landtypes = 79;
static const int landtypes = 81;
struct landtype {
int color;
@ -184,7 +186,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
laMirrorWall, laMirrored, laMirrorWall2, laMirrored2,
laMirrorOld,
laVolcano, laBlizzard, laHunting, laTerracotta, laMercuryRiver,
laDual, laSnakeNest
laDual, laSnakeNest, laDocks, laInvincible
};
enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gGUARD};

View File

@ -84,8 +84,12 @@ int arg::readCommon() {
char *c = args();
using namespace patterns;
subpattern_flags = 0;
whichPattern = 0;
while(*c) {
if(*c >= '0' && *c <= '9') subpattern_flags ^= 1 << (*c - '0');
else if(*c == '@') subpattern_flags ^= 1 << 10;
else if(*c == '-') subpattern_flags ^= 1 << 11;
else if(*c == '~') subpattern_flags ^= 1 << 12;
else whichPattern = *c;
c++;
}

View File

@ -1994,7 +1994,8 @@ namespace heat {
}
else if(c2->wall == waVinePlant || c2->wall == waRose || c2->wall == waSaloon ||
c2->wall == waWeakBranch || c2->wall == waCanopy || c2->wall == waTrunk || c2->wall == waSolidBranch ||
c2->wall == waBigBush || c2->wall == waSmallBush || c2->wall == waBonfireOff || c2->wall == waSmallTree)
c2->wall == waBigBush || c2->wall == waSmallBush || c2->wall == waBonfireOff || c2->wall == waSmallTree ||
c2->wall == waDock)
newfires.emplace_back(c2, 12);
else if(cellHalfvine(c2) && last && last->wall == c2->wall)
newfires.emplace_back(c2, 12);
@ -2005,7 +2006,7 @@ namespace heat {
}
if(hasTimeout(c)) {
if(c->mpdist == 8 && (c->land == laWineyard || c->land == laEndorian)) {
if(c->mpdist == 8 && (c->land == laWineyard || c->land == laEndorian || c->land == laDocks)) {
// do not expire, do not store in 'offscreen', do not generate more land
}
else {

View File

@ -46,7 +46,7 @@ bool boatStrandable(cell *c) {
// monster/wall types
bool isFire(cell *w) {
return w->wall == waFire || w->wall == waPartialFire || w->wall == waEternalFire;
return w->wall == waFire || w->wall == waPartialFire || w->wall == waEternalFire || w->wall == waBurningDock;
}
bool isFireOrMagma(cell *w) {
@ -68,7 +68,7 @@ bool isActivable(cell *c) {
bool hasTimeout(cell *c) {
return c->wall == waThumperOn || c->wall == waFire || c->wall == waPartialFire ||
c->wall == waTempWall || c->wall == waTempFloor || c->wall == waTempBridge ||
c->wall == waTempBridgeBlocked;
c->wall == waTempBridgeBlocked || c->wall == waBurningDock;
}
bool isMimic(eMonster m) {
@ -275,7 +275,8 @@ int itemclass(eItem i) {
i == itSlime || i == itAmethyst || i == itDodeca ||
i == itGreenGrass || i == itBull ||
i == itLavaLily || i == itHunting ||
i == itBlizzard || i == itTerra || i == itGlowCrystal || i == itSnake
i == itBlizzard || i == itTerra || i == itGlowCrystal || i == itSnake ||
i == itDock || i == itInvix
)
return IC_TREASURE;
if(i == itSavedPrincess || i == itStrongWind || i == itWarning)
@ -338,7 +339,8 @@ bool isWall(cell *w) {
w->wall == waWeakBranch || w->wall == waCanopy || w->wall == waTower ||
w->wall == waSmallBush || w->wall == waBigBush ||
w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor ||
w->wall == waSlime1 || w->wall == waSlime2 || w->wall == waArrowTrap || w->wall == waMagma)
w->wall == waSlime1 || w->wall == waSlime2 || w->wall == waArrowTrap || w->wall == waMagma ||
w->wall == waDock)
return false;
if(isWatery(w) || isChasmy(w) || isFire(w)) return false;
return true;

View File

@ -825,7 +825,7 @@ void useup(cell *c) {
drawParticles(c, c->wall == waFire ? 0xC00000 : winf[c->wall].color, 10, 50);
if(c->wall == waTempFloor)
c->wall = waChasm;
else if(c->wall == waTempBridge || c->wall == waTempBridgeBlocked)
else if(c->wall == waTempBridge || c->wall == waTempBridgeBlocked || c->wall == waBurningDock)
placeWater(c, c);
else
c->wall = c->land == laCaribbean ? waCIsland2 : waNone;
@ -1640,6 +1640,12 @@ bool makeflame(cell *c, int timeout, bool checkonly) {
c->wall != waSaloon && c->wall != waRose) return false;
// reptiles are able to use the water to put the fire off
else if(c->wall == waReptileBridge) return false;
else if(c->wall == waDock) {
if(checkonly) return true;
c->wall = waBurningDock;
c->wparam = 3;
return false;
}
else {
eWall w = eternalFire(c) ? waEternalFire : waFire;
if(!checkonly) drawFireParticles(c, 10);
@ -2909,6 +2915,10 @@ bool makeEmpty(cell *c) {
;
else if(c->wall == waGiantRug)
;
else if(c->wall == waDock)
;
else if(c->land == laDocks)
c->wall = waBoat;
else if(c->wall == waFreshGrave && bounded)
;
else if(isReptile(c->wall))
@ -3264,7 +3274,10 @@ void moveMonster(cell *ct, cell *cf) {
}
else if(isFire(c2) && c2->wall != waEternalFire) {
addMessage(XLAT("%The1 is extinguished!", c2->wall, moWaterElemental));
c2->wall = waNone;
if(c2->wall == waBurningDock)
c2->wall = waDock;
else
c2->wall = waNone;
}
if(shmup::on && isWatery(c2)) shmup::destroyBoats(c2);
}

View File

@ -2443,6 +2443,9 @@ void setcolors(cell *c, int& wcol, int &fcol) {
if(nearshore) mafcol += 30; */
fcol = fcol + mafcol * (4+sin(ticks / 500. + ((euclid||c->master->alt) ? celldistAlt(c) : 0)*1.5))/5;
}
else if(c->land == laDocks) {
fcol = 0x0000A0;
}
else if(c->land == laAlchemist)
fcol = 0x900090;
else if(c->land == laWhirlpool)
@ -2471,6 +2474,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
case laDesert: fcol = 0xEDC9AF; break;
case laKraken: fcol = 0x20A020; break;
case laDocks: fcol = 0x202020; break;
case laCA: fcol = 0x404040; break;
case laMotion: fcol = 0xF0F000; break;
case laGraveyard: fcol = 0x107010; break;
@ -2757,7 +2761,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
fcol = wcol = winf[c->wall].color; */
// floors become fcol
if(c->wall == waSulphur || c->wall == waSulphurC || c->wall == waPlatform || c->wall == waMercury)
if(c->wall == waSulphur || c->wall == waSulphurC || c->wall == waPlatform || c->wall == waMercury || c->wall == waDock)
fcol = wcol;
if(isAlch(c)) {
@ -3142,6 +3146,7 @@ int getfd(cell *c) {
return (c->wall == waMercury && wmspatial) ? 0 : 1;
case laKraken:
case laDocks:
case laBurial:
case laIvoryTower:
case laDungeon:
@ -3873,6 +3878,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
else if(c->land == laKraken)
qfloor(c, Vf, FULLFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laDocks)
qfloor(c, Vf, FULLFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laLivefjord)
qfloor(c, Vf, CAVEFLOOR, darkena(fcol, fd, 0xFF));
@ -4263,6 +4271,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
queuepoly(V, shBigCarpet2, darkena(0x600000, 0, 0xFF));
queuepoly(V, shBigCarpet3, darkena(0xC09F00, 0, 0xFF));
}
else if(c->wall == waDock) ;
else if(xch != '.' && xch != '+' && xch != '>' && xch != ':'&& xch != '-' && xch != ';' && c->wall != waSulphur && c->wall != waMercury && xch != ',' && xch != '&')
error = true;

View File

@ -690,6 +690,7 @@ namespace patterns {
static const int SPF_ALTERNATE = 128;
static const int SPF_FOOTBALL = 256;
static const int SPF_FULLSYM = 512;
static const int SPF_DOCKS = 1024;
static const int SPF_SYM0123 = SPF_SYM01 | SPF_SYM02 | SPF_SYM03;

View File

@ -1876,6 +1876,34 @@ void giantLandSwitch(cell *c, int d, cell *from) {
}
break;
case laDocks: {
if(d == 8) {
patterns::patterninfo si;
patterns::val38(c, si, patterns::SPF_DOCKS, patterns::PAT_COLORING);
c->wall = waSea;
if(among(si.id, 0, 4, 16, nontruncated ? -1 : 24))
c->wall = waDock;
if(si.id == 8 && hrand(100) < 75) {
c->wall = waBoat;
for(int i=0; i<c->type; i++) {
patterns::val38(createMov(c, i), si, patterns::SPF_DOCKS, patterns::PAT_COLORING);
if(si.id == 0) c->mondir = i;
}
}
}
if(d == 7 && !safety) {
patterns::patterninfo si;
patterns::val38(c, si, patterns::SPF_DOCKS, patterns::PAT_COLORING);
if(si.id == 16 && hrand(250) < PT(30 + kills[moRatling] + kills[moCShark] + kills[moAlbatross] + kills[moPirate] + kills[moFireFairy], 100))
c->item = itDock;
if(c->wall == waDock && hrand(6000) < 25 + items[itDock] + yendor::hardness())
c->monst = pick(moPirate, moRatling, moFireFairy);
if(c->wall == waSea && hrand(6000) < 25 + items[itDock] + yendor::hardness())
c->monst = pick(moCShark, moAlbatross);
}
break;
}
case laEAir:
case laEWater:
case laEEarth:

View File

@ -205,6 +205,9 @@ int isNative(eLand l, eMonster m) {
return m == moHexSnake ? 2 : 0;
case laCA: return 0;
case laDocks:
return among(m, moRatling, moPirate, moCShark, moAlbatross, moFireFairy) ? 2 : 0;
}
return false;
}
@ -298,6 +301,8 @@ eItem treasureType(eLand l) {
case laHunting: return itHunting;
case laDual: return itGlowCrystal;
case laSnakeNest: return itSnake;
case laDocks: return itDock;
case laInvincible: return itInvix;
case laCA: return itNone;
}
@ -412,6 +417,7 @@ bool landUnlocked(eLand l) {
case laMirror: case laMinefield: case laPalace:
case laOcean: case laLivefjord: case laMirrored: case laMirrorWall: case laMirrorWall2:
case laDocks:
case laMirrored2:
return gold() >= R30;
@ -945,7 +951,7 @@ vector<eLand> land_over = {
laHell, laCrossroads3, laCocytus, laPower, laCrossroads4,
laCrossroads5,
// EXTRA
laWildWest, laHalloween, laDual, laSnakeNest, laCA
laWildWest, laHalloween, laDual, laSnakeNest, laDocks, laInvincible, laCA
};
vector<eLand> landlist;
@ -1196,6 +1202,9 @@ int isLandValid(eLand l) {
if(l == laSnakeNest)
return geosupport_threecolor() ? 3 : 0;
if(l == laDocks)
return a38 ? 2 : 0;
if(l == laStorms && torus)
return 3;

View File

@ -408,6 +408,11 @@ void wandering() {
playSeenSound(c);
continue;
}
if(c->land == laDocks && wchance(items[itDock], 25) && canReachPlayer(c, moEagle)) {
c->monst = moAlbatross;
playSeenSound(c);
continue;
}
if(!peace::on && c->land == laLivefjord && wchance(items[itFjord], 80) && items[itFjord] >= 10 && canReachPlayer(c, moWaterElemental)) {
c->monst = moWaterElemental;
playSeenSound(c);

View File

@ -1,4 +1,4 @@
#define ORBLINES 63
#define ORBLINES 66
// orbgen flags
@ -81,7 +81,7 @@ const orbinfo orbinfos[ORBLINES] = {
{orbgenflags::S_NAT_NT, laLivefjord, 0, 1800, itOrbFish},
{orbgenflags::S_NAT_NT, laPrincessQuest, 0, 200, itOrbLove},
{orbgenflags::S_NATIVE, laIvoryTower, 500, 4000, itOrbMatter},
{orbgenflags::S_NAT_NT , laElementalWall, 1500, 4000, itOrbSummon},
{orbgenflags::S_NAT_NT, laElementalWall, 1500, 4000, itOrbSummon},
{orbgenflags::S_NATIVE, laStorms, 1000, 2500, itOrbStunning},
{orbgenflags::S_NAT_NT, laOvergrown, 1000, 800, itOrbLuck},
{orbgenflags::S_NATIVE, laWhirlwind, 1250, 3000, itOrbAir},
@ -108,6 +108,9 @@ const orbinfo orbinfos[ORBLINES] = {
{orbgenflags::S_NATIVE, laTerracotta, 800, 2500, itOrbSide1},
{orbgenflags::S_NATIVE, laDual, 600, 2500, itOrbSide2},
{orbgenflags::S_GUEST, laSnakeNest, 2000, 0, itOrbDomination},
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbFish},
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDragon},
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDash},
{orbgenflags::S_NATIVE, laWhirlpool, 0, 2000, itOrbWater}, // needs to be last
};

View File

@ -423,6 +423,7 @@ void castLightningBolt(cellwalker lig) {
makeflame(c, 4, false);
brk = true;
}
if(c->wall == waDock) makeflame(c, 5, false);
if(c->wall == waCTree) makeflame(c, 12, false);
if(c->wall == waRose) makeflame(c, 60, false);
if(cellHalfvine(c) && c->mov[lig.spin] && c->wall == c->mov[lig.spin]->wall) {

View File

@ -549,17 +549,25 @@ namespace patterns {
si.id += 8;
si.id %= 12;
applyAlt(si, sub, pat);
if((sub & SPF_DOCKS) && (c->master->fiftyval & 32))
si.id += 16, si.symmetries = 4;
}
else {
si.id = 8 * ((c->master->fiftyval & 1) ^ (c->spin(0) & 1));
bool dock = false;
for(int i=0; i<c->type; i+=2) {
int fv = (createMov(c, i)->master->fiftyval >> 1) & 3;
if(fv == 0) si.dir = (si.id == 8 && pat == PAT_COLORING ? 1 : 0) + i;
int fiv = createMov(c, i)->master->fiftyval;
int fv = (fiv >> 1) & 3;
if(fv == 0) {
si.dir = (si.id == 8 && pat == PAT_COLORING ? 1 : 0) + i;
if(fiv & 32) dock = true;
}
}
if(symRotation) si.symmetries = 2;
si.id += 8;
si.id %= 12;
applyAlt(si, sub, pat);
if(dock && (sub & SPF_DOCKS)) si.id += 16;
}
}
@ -829,6 +837,11 @@ namespace patterns {
si.symmetries = 6;
}
else if(pat == PAT_PALACE) {
val_nopattern(c, si, sub);
si.id = c->master->fiftyval;
}
else if(pat == PAT_DOWN) {
si.id = towerval(c);
si.dir = downdir(c);

View File

@ -1118,18 +1118,26 @@ int zebra_heptagon(int parent, int dir) {
int fifty_38(int f, int d) {
// This creates the 'p' pattern for the a38 geometry.
// Hexagons have codes 4 and 5, while octagons have 0, 1, 2.
// Hexagons have codes 4 and 8, while octagons have 0, 1, 2.
// Heptagons also have a 'dock flag' which is flipped
// for almost-adjacent octagons of the same code
// f&1 is which direction is the hexagon with code '4'
// c=((f>>1)&3) is 0, 1, or 2
int c = ((f>>1)&3);
// f&8: in which direction is c increasing by one
int step = (f&8) ? 1 : 2; if(d&1) step ^= 3;
// (f>>3)&3: in which direction is c increasing by one (keeping the dock flag)
int ssub = (f>>3) & 3;
// f&32: dock flags
int dockflip[2][4] = {{1+24, 2+0, 1+32+8, 2+32+0}, {1+8, 2+32+16, 1+32+24, 2+16}};
int d2 = (d-ssub) & 3;
int dock = (f>>5) & 1;
return
((f ^ d ^ 1) & 1)
+ (((c + step) % 3) << 1)
+ (step==2?8:0);
+ (((c + (dockflip[dock][d2]&3)) % 3) << 1)
+ (dockflip[dock][d2]&~3);
}