mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
new lands for 10.1 -- initial commit
This commit is contained in:
parent
14e4fe9a60
commit
fe34a4a555
54
classes.cpp
54
classes.cpp
@ -346,7 +346,7 @@ const char *mirroreddesc =
|
|||||||
"Mirror walls reflect Mimics, lightning bolts, and "
|
"Mirror walls reflect Mimics, lightning bolts, and "
|
||||||
"missiles perfectly.";
|
"missiles perfectly.";
|
||||||
|
|
||||||
const int motypes = 141;
|
const int motypes = 150;
|
||||||
|
|
||||||
struct monstertype {
|
struct monstertype {
|
||||||
char glyph;
|
char glyph;
|
||||||
@ -696,6 +696,14 @@ monstertype minf[motypes] = {
|
|||||||
"If you attack a Mirror Spirit physically, it is delayed, but not destroyed -- "
|
"If you attack a Mirror Spirit physically, it is delayed, but not destroyed -- "
|
||||||
"more reflections will come out of the mirror. Use Mimics to destroy them."
|
"more reflections will come out of the mirror. Use Mimics to destroy them."
|
||||||
},
|
},
|
||||||
|
{ 'W', 0x202020, "Hunting Dog", NODESC},
|
||||||
|
{ 'T', 0xA0A0A0, "Terracotta Warrior", NODESC},
|
||||||
|
{ 'H', 0xA0A0A0, "Mercury Warrior", NODESC},
|
||||||
|
{ 'B', 0xA00000, "Void Beast", NODESC},
|
||||||
|
{ 'L', 0xA00000, "Lemur", NODESC},
|
||||||
|
{ 'W', 0x202020, "Hunting Dog (guarding)", NODESC},
|
||||||
|
{ 'G', 0xC0C0FF, "Ice Golem", NODESC},
|
||||||
|
{ 'B', 0xC0C0FF, "Sand Bird", NODESC},
|
||||||
|
|
||||||
// shmup specials
|
// shmup specials
|
||||||
{ '@', 0xC0C0C0, "Rogue", "In the Shoot'em Up mode, you are armed with thrown Knives."},
|
{ '@', 0xC0C0C0, "Rogue", "In the Shoot'em Up mode, you are armed with thrown Knives."},
|
||||||
@ -706,10 +714,11 @@ monstertype minf[motypes] = {
|
|||||||
{ '*', 0xFFFFFF, "Airball", "This magical missile pushes back whatever it hits."},
|
{ '*', 0xFFFFFF, "Airball", "This magical missile pushes back whatever it hits."},
|
||||||
// technical
|
// technical
|
||||||
{ '?', 0x00C000, "dead bug", NODESC},
|
{ '?', 0x00C000, "dead bug", NODESC},
|
||||||
{ '?', 0xFFFF00, "electric discharge", NODESC}, // appears as 'killed by electrocution'
|
{ '?', 0xFFFF00, "electric discharge", NODESC}, // appears as 'killed by electric discharge'
|
||||||
{ '?', 0xE06000, "dead bird", NODESC},
|
{ '?', 0xE06000, "dead bird", NODESC},
|
||||||
{ '?', 0xE06000, "Energy Sword", NODESC},
|
{ '?', 0xE06000, "Energy Sword", NODESC},
|
||||||
{ '!', 0xFF0000, "Warning", warningdesc},
|
{ '!', 0xFF0000, "Warning", warningdesc},
|
||||||
|
{ '!', 0xFF0000, "arrow trap", NODESC},
|
||||||
{ '*', 0, "vertex", "A vertex from rogueviz."}
|
{ '*', 0, "vertex", "A vertex from rogueviz."}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -756,10 +765,12 @@ enum eMonster {
|
|||||||
moVampire, moBat, moReptile,
|
moVampire, moBat, moReptile,
|
||||||
moHerdBull, moRagingBull, moSleepBull,
|
moHerdBull, moRagingBull, moSleepBull,
|
||||||
moButterfly, moNarciss, moMirrorSpirit,
|
moButterfly, moNarciss, moMirrorSpirit,
|
||||||
|
moHunterDog, moTerraWarrior, moMercuryGuy, moVoidBeast, moLemur, moHunterGuard,
|
||||||
|
moIceGolem, moSandBird,
|
||||||
// shmup specials
|
// shmup specials
|
||||||
moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball,
|
moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball,
|
||||||
// temporary
|
// temporary
|
||||||
moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning,
|
moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning, moArrowTrap,
|
||||||
moRogueviz
|
moRogueviz
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -790,7 +801,7 @@ genderswitch_t genderswitch[NUM_GS] = {
|
|||||||
|
|
||||||
// --- items ---
|
// --- items ---
|
||||||
|
|
||||||
const int ittypes = 112;
|
const int ittypes = 119;
|
||||||
|
|
||||||
struct itemtype {
|
struct itemtype {
|
||||||
char glyph;
|
char glyph;
|
||||||
@ -1183,6 +1194,13 @@ itemtype iinf[ittypes] = {
|
|||||||
},
|
},
|
||||||
{ 'O', 0xF0F0F0, "your orbs",
|
{ 'O', 0xF0F0F0, "your orbs",
|
||||||
"Click this to see your orbs."},
|
"Click this to see your orbs."},
|
||||||
|
{ '$', 0xD0D000, "Sage's Stone", NODESCYET},
|
||||||
|
{ '*', 0x40E0D0, "Turquoise", NODESCYET},
|
||||||
|
{ '*', 0x009090, "Forgotten Relic", NODESCYET},
|
||||||
|
{ '*', 0x009090, "Warstone", NODESCYET},
|
||||||
|
{ 'o', 0x307080, "Orb of the Side I", NODESCYET},
|
||||||
|
{ 'o', 0x30A080, "Orb of the Side II", NODESCYET},
|
||||||
|
{ 'o', 0x30D080, "Orb of the Side III", NODESCYET},
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue,
|
enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue,
|
||||||
@ -1216,12 +1234,14 @@ enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBo
|
|||||||
itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat,
|
itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat,
|
||||||
itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns,
|
itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns,
|
||||||
itOrbBull, itBull, itOrbMirror,
|
itOrbBull, itBull, itOrbMirror,
|
||||||
itInventory
|
itInventory,
|
||||||
|
itAlchemy2, itDogPlains, itBlizzard, itTerra,
|
||||||
|
itOrbSide1, itOrbSide2, itOrbSide3
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- wall types ---
|
// --- wall types ---
|
||||||
|
|
||||||
const int walltypes = 100;
|
const int walltypes = 103;
|
||||||
|
|
||||||
struct walltype {
|
struct walltype {
|
||||||
char glyph;
|
char glyph;
|
||||||
@ -1372,8 +1392,8 @@ walltype winf[walltypes] = {
|
|||||||
{ '?', 0xFF00FF, "<earth d", NODESC},
|
{ '?', 0xFF00FF, "<earth d", NODESC},
|
||||||
{ '?', 0xFF00FF, "<elemental tmp>", NODESC},
|
{ '?', 0xFF00FF, "<elemental tmp>", NODESC},
|
||||||
{ '?', 0xFF00FF, "<elemental d>", NODESC},
|
{ '?', 0xFF00FF, "<elemental d>", NODESC},
|
||||||
{ '+', 0x607030, "unnamed floor C", NODESC},
|
{ '+', 0x00F000, "green slime", NODESC},
|
||||||
{ '+', 0xC0C0FF, "unnamed floor D", NODESC},
|
{ '+', 0xF0F000, "yellow slime", NODESC},
|
||||||
{ '#', 0x764e7c, "rosebush", roselanddesc},
|
{ '#', 0x764e7c, "rosebush", roselanddesc},
|
||||||
{ '#', 0xC0C000, "warp gate",
|
{ '#', 0xC0C000, "warp gate",
|
||||||
"This gate separates the warped area from the normal land."},
|
"This gate separates the warped area from the normal land."},
|
||||||
@ -1404,6 +1424,9 @@ walltype winf[walltypes] = {
|
|||||||
{ '#', 0xC0C0FF, "mirror wall", mirroreddesc},
|
{ '#', 0xC0C0FF, "mirror wall", mirroreddesc},
|
||||||
{ '.', 0xE0E0E0, "stepping stones", "A petrified creature."},
|
{ '.', 0xE0E0E0, "stepping stones", "A petrified creature."},
|
||||||
{ '#', 0x309060, "temporary wall", twdesc},
|
{ '#', 0x309060, "temporary wall", twdesc},
|
||||||
|
{ 'S', 0xB0B0B0, "warrior statue", NODESCYET},
|
||||||
|
{ '=', 0xB0B0B0, "bubbling slime", NODESCYET},
|
||||||
|
{ '^', 0xD00000, "arrow trap", NODESCYET},
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCavefloor, waDeadTroll, waDune,
|
enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCavefloor, waDeadTroll, waDune,
|
||||||
@ -1426,7 +1449,7 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
|
|||||||
waCharged, waGrounded, waSandstone, waSaloon, waMetal,
|
waCharged, waGrounded, waSandstone, waSaloon, waMetal,
|
||||||
waDeadTroll2, waFan,
|
waDeadTroll2, waFan,
|
||||||
waTemporary, waEarthD, waElementalTmp, waElementalD,
|
waTemporary, waEarthD, waElementalTmp, waElementalD,
|
||||||
waFloorC, waFloorD, waRose, waWarpGate,
|
waSlime1, waSlime2, waRose, waWarpGate,
|
||||||
waTrunk, waSolidBranch, waWeakBranch, waCanopy,
|
waTrunk, waSolidBranch, waWeakBranch, waCanopy,
|
||||||
waBarrowWall, waBarrowDig,
|
waBarrowWall, waBarrowDig,
|
||||||
waPetrified, waTower,
|
waPetrified, waTower,
|
||||||
@ -1435,12 +1458,14 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
|
|||||||
waInvisibleFloor,
|
waInvisibleFloor,
|
||||||
waMirrorWall,
|
waMirrorWall,
|
||||||
waPetrifiedBridge,
|
waPetrifiedBridge,
|
||||||
waTempBridgeBlocked
|
waTempBridgeBlocked,
|
||||||
|
waTerraWarrior, waBubble,
|
||||||
|
waArrowTrap
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- land types ---
|
// --- land types ---
|
||||||
|
|
||||||
const int landtypes = 73;
|
const int landtypes = 76;
|
||||||
|
|
||||||
struct landtype {
|
struct landtype {
|
||||||
int color;
|
int color;
|
||||||
@ -1623,7 +1648,10 @@ const landtype linf[landtypes] = {
|
|||||||
{ 0xC8C8FF, "Reflection", mirroreddesc},
|
{ 0xC8C8FF, "Reflection", mirroreddesc},
|
||||||
{ 0xC8C8FF, "Mirror Land",
|
{ 0xC8C8FF, "Mirror Land",
|
||||||
"A strange land which contains mirrors and mirages, protected by Mirror Rangers."},
|
"A strange land which contains mirrors and mirages, protected by Mirror Rangers."},
|
||||||
{ 0xFFFFFF, "Alchemy II", NODESCYET}
|
{ 0xA06000, "Alchemy II", NODESCYET},
|
||||||
|
{ 0x8080FF, "Blizzard", NODESCYET},
|
||||||
|
{ 0x207068, "Hunting Ground", NODESCYET},
|
||||||
|
{ 0x888888, "Terracotta Army", NODESCYET}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle, laAlchemist, laMirror, laGraveyard,
|
enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle, laAlchemist, laMirror, laGraveyard,
|
||||||
@ -1643,7 +1671,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
|
|||||||
laPrairie, laBull, laCrossroads5, laCA,
|
laPrairie, laBull, laCrossroads5, laCA,
|
||||||
laMirrorWall, laMirrored, laMirrorWall2, laMirrored2,
|
laMirrorWall, laMirrored, laMirrorWall2, laMirrored2,
|
||||||
laMirrorOld,
|
laMirrorOld,
|
||||||
laAlchemy2
|
laAlchemy2, laBlizzard, laDogPlains, laTerracotta
|
||||||
};
|
};
|
||||||
|
|
||||||
// cell information for the game
|
// cell information for the game
|
||||||
|
47
complex.cpp
47
complex.cpp
@ -1195,8 +1195,12 @@ namespace mirror {
|
|||||||
cell *c2 = cw2.c;
|
cell *c2 = cw2.c;
|
||||||
if(c2->monst) {
|
if(c2->monst) {
|
||||||
c->monst = moMimic;
|
c->monst = moMimic;
|
||||||
if(!peace::on && canAttack(c,moMimic,c2,c2->monst, 0))
|
eMonster m2 = c2->monst;
|
||||||
|
if(!peace::on && canAttack(c,moMimic,c2,m2, 0)) {
|
||||||
attackMonster(c2, AF_MSG | AF_ORSTUN, moMimic);
|
attackMonster(c2, AF_MSG | AF_ORSTUN, moMimic);
|
||||||
|
if(!fwd) produceGhost(c2, m2, moMimic);
|
||||||
|
sideAttack(c, m.second.spin, m2, 0);
|
||||||
|
}
|
||||||
c->monst = moNone;
|
c->monst = moNone;
|
||||||
}
|
}
|
||||||
if(c2->wall == waBigTree)
|
if(c2->wall == waBigTree)
|
||||||
@ -1758,9 +1762,13 @@ inline float& HEAT(cell *c) { return c->LHU.heat; }
|
|||||||
|
|
||||||
namespace heat {
|
namespace heat {
|
||||||
|
|
||||||
|
void affect(cell *c, double delta) {
|
||||||
|
if(isIcyLand(c)) HEAT(c) += delta;
|
||||||
|
}
|
||||||
|
|
||||||
double absheat(cell *c) {
|
double absheat(cell *c) {
|
||||||
if(c->land == laCocytus) return HEAT(c) -.6;
|
if(c->land == laCocytus) return HEAT(c) -.6;
|
||||||
if(c->land == laIce) return HEAT(c) -.4;
|
if(c->land == laIce || c->land == laBlizzard) return HEAT(c) -.4;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1850,21 +1858,30 @@ namespace heat {
|
|||||||
forCellEx(ct, c) if(!isIcyLand(ct) && isFire(ct))
|
forCellEx(ct, c) if(!isIcyLand(ct) && isFire(ct))
|
||||||
hmod += xrate*.1;
|
hmod += xrate*.1;
|
||||||
|
|
||||||
for(int j=0; j<c->type; j++) if(c->mov[j]) {
|
forCellEx(ct, c) {
|
||||||
if(!isIcyLand(c->mov[j])) {
|
if(!isIcyLand(ct)) {
|
||||||
// make sure that we can still enter Cocytus,
|
// make sure that we can still enter Cocytus,
|
||||||
// it won't heat up right away even without Orb of Winter or Orb of Speed
|
// it won't heat up right away even without Orb of Winter or Orb of Speed
|
||||||
if(isPlayerOn(c->mov[j]) && (c->land == laIce || markOrb(itOrbWinter)))
|
if(isPlayerOn(ct) && (c->land == laIce || markOrb(itOrbWinter)))
|
||||||
hmod += (markOrb(itOrbWinter) ? -1.2 : 1.2) / 4 * xrate;
|
hmod += (markOrb(itOrbWinter) ? -1.2 : 1.2) / 4 * xrate;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ld hdiff = absheat(c->mov[j]) - absheat(c);
|
ld hdiff = absheat(ct) - absheat(c);
|
||||||
hdiff /= 10;
|
hdiff /= 10;
|
||||||
if(shmup::on && (c->land == laCocytus || c->mov[j]->land == laCocytus))
|
|
||||||
|
if(ct->land == laBlizzard) {
|
||||||
|
int v = (windmap::at(ct) - windmap::at(c)) & 255;
|
||||||
|
if(v > 128) v -= 256;
|
||||||
|
if(v < windmap::NOWINDFROM && v > -windmap::NOWINDFROM)
|
||||||
|
hdiff = hdiff * (1 - v * 5. / windmap::NOWINDFROM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shmup::on && (c->land == laCocytus || ct->land == laCocytus))
|
||||||
hdiff /= 3;
|
hdiff /= 3;
|
||||||
// if(c->mov[j]->cpdist > 7 && !quotient) hdiff += -HEAT(c) / 30;
|
// if(c->mov[j]->cpdist > 7 && !quotient) hdiff += -HEAT(c) / 30;
|
||||||
hmod += hdiff;
|
hmod += hdiff;
|
||||||
}
|
}
|
||||||
|
// printf("%d ", vsum);
|
||||||
|
|
||||||
hmods[i] = hmod;
|
hmods[i] = hmod;
|
||||||
}
|
}
|
||||||
@ -1971,7 +1988,16 @@ namespace heat {
|
|||||||
useup(c);
|
useup(c);
|
||||||
offscreen2.push_back(c);
|
offscreen2.push_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c->wall == waArrowTrap && c->wparam) {
|
||||||
|
c->wparam++;
|
||||||
|
if(c->wparam == 3) {
|
||||||
|
if(canAttack(c, moArrowTrap, c, c->monst, AF_GETPLAYER))
|
||||||
|
attackMonster(c, AF_ORSTUN | AF_MSG | AF_GETPLAYER, moArrowTrap);
|
||||||
|
}
|
||||||
|
if(c->wparam == 4) c->wparam = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<size(newfires); i++) {
|
for(int i=0; i<size(newfires); i++) {
|
||||||
@ -3044,5 +3070,10 @@ namespace windmap {
|
|||||||
printf(" return;\n");
|
printf(" return;\n");
|
||||||
printf(" }\n");
|
printf(" }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int at(cell *c) {
|
||||||
|
return windmap::windcodes[windmap::getId(c)];
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +159,7 @@ bool applyCheat(char u, cell *c = NULL) {
|
|||||||
flipplayer = false;
|
flipplayer = false;
|
||||||
mirror::act(1, mirror::SPINSINGLE);
|
mirror::act(1, mirror::SPINSINGLE);
|
||||||
cwspin(cwt, 1);
|
cwspin(cwt, 1);
|
||||||
|
wavephase = (1+wavephase) & 7;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(u == 'J') {
|
if(u == 'J') {
|
||||||
|
25
flags.cpp
25
flags.cpp
@ -4,7 +4,7 @@
|
|||||||
// Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details
|
// Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details
|
||||||
|
|
||||||
bool isIcyLand(eLand l) {
|
bool isIcyLand(eLand l) {
|
||||||
return l == laIce || l == laCocytus;
|
return l == laIce || l == laCocytus || l == laBlizzard;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isIcyLand(cell *c) {
|
bool isIcyLand(cell *c) {
|
||||||
@ -24,7 +24,7 @@ bool isWatery(cell *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isChasmy(cell *c) {
|
bool isChasmy(cell *c) {
|
||||||
return c->wall == waChasm || c->wall == waSulphur || c->wall == waSulphurC;
|
return c->wall == waChasm || c->wall == waSulphur || c->wall == waSulphurC || c->wall == waBubble;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isWateryOrBoat(cell *c) {
|
bool isWateryOrBoat(cell *c) {
|
||||||
@ -267,7 +267,10 @@ int itemclass(eItem i) {
|
|||||||
i == itBabyTortoise || i == itDragon || i == itApple ||
|
i == itBabyTortoise || i == itDragon || i == itApple ||
|
||||||
i == itKraken || i == itBarrow || i == itTrollEgg || i == itTreat ||
|
i == itKraken || i == itBarrow || i == itTrollEgg || i == itTreat ||
|
||||||
i == itSlime || i == itAmethyst || i == itDodeca ||
|
i == itSlime || i == itAmethyst || i == itDodeca ||
|
||||||
i == itGreenGrass || i == itBull)
|
i == itGreenGrass || i == itBull ||
|
||||||
|
i == itAlchemy2 || i == itDogPlains ||
|
||||||
|
i == itBlizzard || i == itTerra
|
||||||
|
)
|
||||||
return IC_TREASURE;
|
return IC_TREASURE;
|
||||||
if(i == itSavedPrincess || i == itStrongWind || i == itWarning)
|
if(i == itSavedPrincess || i == itStrongWind || i == itWarning)
|
||||||
return IC_NAI;
|
return IC_NAI;
|
||||||
@ -281,10 +284,18 @@ bool isAlch(eWall w) {
|
|||||||
return w == waFloorA || w == waFloorB;
|
return w == waFloorA || w == waFloorB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAlch2(eWall w, bool bubbletoo) {
|
||||||
|
return w == waSlime1 || w == waSlime2 || (bubbletoo && w == waBubble);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAlch2(cell *c, bool bubbletoo) {
|
||||||
|
return isAlch2(c->wall, bubbletoo);
|
||||||
|
}
|
||||||
|
|
||||||
bool isAlch(cell *c) { return isAlch(c->wall); }
|
bool isAlch(cell *c) { return isAlch(c->wall); }
|
||||||
|
|
||||||
bool isAlchAny(eWall w) {
|
bool isAlchAny(eWall w) {
|
||||||
return w == waFloorA || w == waFloorB || w == waFloorC || w == waFloorD;
|
return w == waFloorA || w == waFloorB;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAlchAny(cell *c) { return isAlchAny(c->wall); }
|
bool isAlchAny(cell *c) { return isAlchAny(c->wall); }
|
||||||
@ -320,7 +331,8 @@ bool isWall(cell *w) {
|
|||||||
w->wall == waLadder || w->wall == waTrunk || w->wall == waSolidBranch ||
|
w->wall == waLadder || w->wall == waTrunk || w->wall == waSolidBranch ||
|
||||||
w->wall == waWeakBranch || w->wall == waCanopy || w->wall == waTower ||
|
w->wall == waWeakBranch || w->wall == waCanopy || w->wall == waTower ||
|
||||||
w->wall == waSmallBush || w->wall == waBigBush ||
|
w->wall == waSmallBush || w->wall == waBigBush ||
|
||||||
w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor)
|
w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor ||
|
||||||
|
w->wall == waSlime1 || w->wall == waSlime2 || w->wall == waArrowTrap)
|
||||||
return false;
|
return false;
|
||||||
if(isWatery(w) || isChasmy(w) || isFire(w)) return false;
|
if(isWatery(w) || isChasmy(w) || isFire(w)) return false;
|
||||||
return true;
|
return true;
|
||||||
@ -362,7 +374,8 @@ bool normalMover(eMonster m) {
|
|||||||
m == moRoseBeauty || m == moWolf ||
|
m == moRoseBeauty || m == moWolf ||
|
||||||
m == moResearcher || m == moRagingBull ||
|
m == moResearcher || m == moRagingBull ||
|
||||||
m == moNarciss || m == moMirrorSpirit ||
|
m == moNarciss || m == moMirrorSpirit ||
|
||||||
slowMover(m);
|
m == moHunterDog || m == moTerraWarrior || m == moMercuryGuy || m == moLemur || m == moHunterGuard ||
|
||||||
|
m == moIceGolem || slowMover(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from-to
|
// from-to
|
||||||
|
402
game.cpp
402
game.cpp
@ -23,30 +23,31 @@ int hardcoreAt;
|
|||||||
|
|
||||||
flagtype havewhat, hadwhat;
|
flagtype havewhat, hadwhat;
|
||||||
|
|
||||||
#define HF_BUG (1<<0)
|
#define HF_BUG Flag(0)
|
||||||
#define HF_EARTH (1<<1)
|
#define HF_EARTH Flag(1)
|
||||||
#define HF_BIRD (1<<2)
|
#define HF_BIRD Flag(2)
|
||||||
#define HF_LEADER (1<<3)
|
#define HF_LEADER Flag(3)
|
||||||
#define HF_HEX (1<<4)
|
#define HF_HEX Flag(4)
|
||||||
#define HF_WHIRLPOOL (1<<5)
|
#define HF_WHIRLPOOL Flag(5)
|
||||||
#define HF_WATER (1<<6)
|
#define HF_WATER Flag(6)
|
||||||
#define HF_AIR (1<<7)
|
#define HF_AIR Flag(7)
|
||||||
#define HF_MUTANT (1<<8)
|
#define HF_MUTANT Flag(8)
|
||||||
#define HF_OUTLAW (1<<9)
|
#define HF_OUTLAW Flag(9)
|
||||||
#define HF_WHIRLWIND (1<<10)
|
#define HF_WHIRLWIND Flag(10)
|
||||||
#define HF_ROSE (1<<11)
|
#define HF_ROSE Flag(11)
|
||||||
#define HF_DRAGON (1<<12)
|
#define HF_DRAGON Flag(12)
|
||||||
#define HF_KRAKEN (1<<13)
|
#define HF_KRAKEN Flag(13)
|
||||||
#define HF_SHARK (1<<14)
|
#define HF_SHARK Flag(14)
|
||||||
#define HF_BATS (1<<15)
|
#define HF_BATS Flag(15)
|
||||||
#define HF_REPTILE (1<<16)
|
#define HF_REPTILE Flag(16)
|
||||||
#define HF_EAGLES (1<<17)
|
#define HF_EAGLES Flag(17)
|
||||||
#define HF_SLOW (1<<18)
|
#define HF_SLOW Flag(18)
|
||||||
#define HF_FAST (1<<19)
|
#define HF_FAST Flag(19)
|
||||||
#define HF_WARP (1<<20)
|
#define HF_WARP Flag(20)
|
||||||
#define HF_MOUSE (1<<21)
|
#define HF_MOUSE Flag(21)
|
||||||
#define HF_RIVER (1<<22)
|
#define HF_RIVER Flag(22)
|
||||||
#define HF_MIRROR (1<<23)
|
#define HF_MIRROR Flag(23)
|
||||||
|
#define HF_VOID Flag(24)
|
||||||
|
|
||||||
bool seenSevenMines = false;
|
bool seenSevenMines = false;
|
||||||
|
|
||||||
@ -332,6 +333,7 @@ int* killtable[] = {
|
|||||||
&kills[moHerdBull], &kills[moSleepBull], &kills[moRagingBull],
|
&kills[moHerdBull], &kills[moSleepBull], &kills[moRagingBull],
|
||||||
&kills[moGadfly], &kills[moButterfly],
|
&kills[moGadfly], &kills[moButterfly],
|
||||||
&kills[moNarciss], &kills[moMirrorSpirit],
|
&kills[moNarciss], &kills[moMirrorSpirit],
|
||||||
|
&kills[moHunterDog], &kills[moIceGolem], &kills[moVoidBeast],
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -459,6 +461,7 @@ bool strictlyAgainstGravity(cell *w, cell *from, bool revdir, flagtype flags) {
|
|||||||
|
|
||||||
bool passable(cell *w, cell *from, flagtype flags) {
|
bool passable(cell *w, cell *from, flagtype flags) {
|
||||||
bool revdir = (flags&P_REVDIR);
|
bool revdir = (flags&P_REVDIR);
|
||||||
|
bool vrevdir = revdir ^ bool(flags&P_VOID);
|
||||||
|
|
||||||
if(from && from != w && nonAdjacent(from, w) && !F(P_IGNORE37 | P_BULLET)) return false;
|
if(from && from != w && nonAdjacent(from, w) && !F(P_IGNORE37 | P_BULLET)) return false;
|
||||||
|
|
||||||
@ -469,7 +472,7 @@ bool passable(cell *w, cell *from, flagtype flags) {
|
|||||||
if(from == pp && F(P_ONPLAYER) && F(P_REVDIR)) return true;
|
if(from == pp && F(P_ONPLAYER) && F(P_REVDIR)) return true;
|
||||||
|
|
||||||
if(from && !((flags & P_ISPLAYER) && getMount(i))) {
|
if(from && !((flags & P_ISPLAYER) && getMount(i))) {
|
||||||
int i = revdir ? incline(w, from) : incline(from, w);
|
int i = vrevdir ? incline(w, from) : incline(from, w);
|
||||||
if(i < -1 && F(P_ROSE)) return false;
|
if(i < -1 && F(P_ROSE)) return false;
|
||||||
if((i > 1) && !F(P_JUMP1 | P_JUMP2 | P_BULLET | P_FLYING | P_BLOW | P_CLIMBUP | P_AETHER | P_REPTILE))
|
if((i > 1) && !F(P_JUMP1 | P_JUMP2 | P_BULLET | P_FLYING | P_BLOW | P_CLIMBUP | P_AETHER | P_REPTILE))
|
||||||
return false;
|
return false;
|
||||||
@ -483,11 +486,11 @@ bool passable(cell *w, cell *from, flagtype flags) {
|
|||||||
if(againstWind(w,from)) return false;
|
if(againstWind(w,from)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(from && strictlyAgainstGravity(w, from, revdir, flags)
|
if(from && strictlyAgainstGravity(w, from, vrevdir, flags)
|
||||||
&& !F(P_GRAVITY | P_BLOW | P_JUMP1 | P_JUMP2 | P_FLYING | P_BULLET | P_AETHER)
|
&& !F(P_GRAVITY | P_BLOW | P_JUMP1 | P_JUMP2 | P_FLYING | P_BULLET | P_AETHER)
|
||||||
) return false;
|
) return false;
|
||||||
|
|
||||||
if(from && (revdir ? againstWind(from,w) : againstWind(w, from)) && !F(P_WIND | P_BLOW | P_JUMP1 | P_JUMP2 | P_BULLET | P_AETHER)) return false;
|
if(from && (vrevdir ? againstWind(from,w) : againstWind(w, from)) && !F(P_WIND | P_BLOW | P_JUMP1 | P_JUMP2 | P_BULLET | P_AETHER)) return false;
|
||||||
|
|
||||||
if(revdir && from && w->monst && passable(from, w, flags &~ (P_REVDIR|P_MONSTER)))
|
if(revdir && from && w->monst && passable(from, w, flags &~ (P_REVDIR|P_MONSTER)))
|
||||||
return true;
|
return true;
|
||||||
@ -621,7 +624,15 @@ void calcAirdir(cell *c) {
|
|||||||
|
|
||||||
bool againstWind(cell *cto, cell *cfrom) {
|
bool againstWind(cell *cto, cell *cfrom) {
|
||||||
if(!cfrom || !cto) return false;
|
if(!cfrom || !cto) return false;
|
||||||
if(airdist(cto) < airdist(cfrom)) return true;
|
int dcto = airdist(cto), dcfrom = airdist(cfrom);
|
||||||
|
if(dcto < dcfrom) return true;
|
||||||
|
if(cfrom->land == laBlizzard && cto->land == laBlizzard && dcto == 3 && dcfrom == 3) {
|
||||||
|
char vfrom = windmap::at(cfrom);
|
||||||
|
char vto = windmap::at(cto);
|
||||||
|
int z = (vfrom-vto) & 255;
|
||||||
|
if(z >= windmap::NOWINDBELOW && z < windmap::NOWINDFROM)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
whirlwind::calcdirs(cfrom);
|
whirlwind::calcdirs(cfrom);
|
||||||
int d = neighborId(cfrom, cto);
|
int d = neighborId(cfrom, cto);
|
||||||
if(whirlwind::winddir(d) == -1) return true;
|
if(whirlwind::winddir(d) == -1) return true;
|
||||||
@ -777,6 +788,8 @@ bool passable_for(eMonster m, cell *w, cell *from, flagtype extra) {
|
|||||||
return passable(w, from, extra | P_ISFRIEND);
|
return passable(w, from, extra | P_ISFRIEND);
|
||||||
if(isWorm(m))
|
if(isWorm(m))
|
||||||
return passable(w, from, extra) && !cellUnstable(w) && ((m != moWorm && m != moTentacle) || !cellEdgeUnstable(w));
|
return passable(w, from, extra) && !cellUnstable(w) && ((m != moWorm && m != moTentacle) || !cellEdgeUnstable(w));
|
||||||
|
if(m == moVoidBeast)
|
||||||
|
return passable(w, from, extra | P_VOID);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,6 +818,7 @@ eMonster movegroup(eMonster m) {
|
|||||||
if(m == moWaterElemental) return moWaterElemental;
|
if(m == moWaterElemental) return moWaterElemental;
|
||||||
if(m == moAirElemental) return moAirElemental;
|
if(m == moAirElemental) return moAirElemental;
|
||||||
if(isBull(m)) return moRagingBull;
|
if(isBull(m)) return moRagingBull;
|
||||||
|
if(m == moVoidBeast) return moVoidBeast;
|
||||||
return moNone;
|
return moNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,6 +973,14 @@ bool stalemate1::isKilled(cell *w) {
|
|||||||
if(canAttack(moveto, who, w, w->monst, flag)) return true;
|
if(canAttack(moveto, who, w, w->monst, flag)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isNeighbor(w, comefrom) && comefrom == moveto && killed) {
|
||||||
|
int d1 = neighborId(comefrom, w);
|
||||||
|
int d2 = neighborId(comefrom, killed);
|
||||||
|
int di = angledist(comefrom->type, d1, d2);
|
||||||
|
if(di && items[itOrbSide1-1+di] && canAttack(moveto, who, w, w->monst, AF_SIDE))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(isNeighbor(w, comefrom) && isNeighbor(w, moveto) && moveto != comefrom)
|
if(isNeighbor(w, comefrom) && isNeighbor(w, moveto) && moveto != comefrom)
|
||||||
if(canAttack(moveto, who, w, w->monst, AF_STAB))
|
if(canAttack(moveto, who, w, w->monst, AF_STAB))
|
||||||
return true;
|
return true;
|
||||||
@ -1279,13 +1301,16 @@ int monstersnear(cell *c, cell *nocount, eMonster who, cell *pushto, cell *comef
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void petrify(cell *c, eWall walltype, eMonster m) {
|
bool petrify(cell *c, eWall walltype, eMonster m) {
|
||||||
destroyHalfvine(c);
|
destroyHalfvine(c);
|
||||||
playSound(c, "die-troll");
|
playSound(c, "die-troll");
|
||||||
|
|
||||||
|
if(walltype == waIcewall && !isIcyLand(c->land))
|
||||||
|
return false;
|
||||||
|
|
||||||
if(isWateryOrBoat(c) && c->land == laWhirlpool) {
|
if(isWateryOrBoat(c) && c->land == laWhirlpool) {
|
||||||
c->wall = waSea;
|
c->wall = waSea;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(walltype == waGargoyle && cellUnstableOrChasm(c))
|
if(walltype == waGargoyle && cellUnstableOrChasm(c))
|
||||||
@ -1296,11 +1321,11 @@ void petrify(cell *c, eWall walltype, eMonster m) {
|
|||||||
walltype = waPetrifiedBridge;
|
walltype = waPetrifiedBridge;
|
||||||
else if((c->wall == waTempBridge || c->wall == waTempBridgeBlocked) && c->land == laWhirlpool) {
|
else if((c->wall == waTempBridge || c->wall == waTempBridgeBlocked) && c->land == laWhirlpool) {
|
||||||
c->wall = waTempBridgeBlocked;
|
c->wall = waTempBridgeBlocked;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
else if(!doesnotFall(c)) {
|
else if(!doesnotFall(c)) {
|
||||||
fallingFloorAnimation(c, walltype, m);
|
fallingFloorAnimation(c, walltype, m);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isReptile(c->wall)) kills[moReptile]++;
|
if(isReptile(c->wall)) kills[moReptile]++;
|
||||||
@ -1308,6 +1333,7 @@ void petrify(cell *c, eWall walltype, eMonster m) {
|
|||||||
c->wall = walltype;
|
c->wall = walltype;
|
||||||
c->wparam = m;
|
c->wparam = m;
|
||||||
c->item = itNone;
|
c->item = itNone;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void killIvy(cell *c, eMonster who) {
|
void killIvy(cell *c, eMonster who) {
|
||||||
@ -1755,6 +1781,7 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
|
|||||||
if(isPrincess(m)) m = moPrincess;
|
if(isPrincess(m)) m = moPrincess;
|
||||||
if(m == moTentacleGhost) m = moGhost;
|
if(m == moTentacleGhost) m = moGhost;
|
||||||
if(!isBulletType(m)) kills[m]++;
|
if(!isBulletType(m)) kills[m]++;
|
||||||
|
if(m == moHunterGuard) m = moHunterDog;
|
||||||
|
|
||||||
if(!c->item) if(m == moButterfly && (deathflags & AF_BULL))
|
if(!c->item) if(m == moButterfly && (deathflags & AF_BULL))
|
||||||
c->item = itBull;
|
c->item = itBull;
|
||||||
@ -1816,6 +1843,12 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
|
|||||||
|
|
||||||
if(connected) petrify(c, waGargoyle, m), pcount = 0;
|
if(connected) petrify(c, waGargoyle, m), pcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m == moIceGolem) {
|
||||||
|
if(petrify(c, waIcewall, m)) pcount = 0;
|
||||||
|
heat::affect(c, -1);
|
||||||
|
forCellEx(c2, c) heat::affect(c2, -.5);
|
||||||
|
}
|
||||||
|
|
||||||
if(m == moTroll) {
|
if(m == moTroll) {
|
||||||
petrify(c, waDeadTroll, m); pcount = 0;
|
petrify(c, waDeadTroll, m); pcount = 0;
|
||||||
@ -2359,6 +2392,10 @@ bool recalcTide;
|
|||||||
#define LANDDIST LHU.bytes[1]
|
#define LANDDIST LHU.bytes[1]
|
||||||
#define CHAOSPARAM LHU.bytes[2]
|
#define CHAOSPARAM LHU.bytes[2]
|
||||||
|
|
||||||
|
int alchemyval(cell *c, int t) {
|
||||||
|
return (windmap::at(c) + (turncount+t)*4) & 255;
|
||||||
|
}
|
||||||
|
|
||||||
void checkTide(cell *c) {
|
void checkTide(cell *c) {
|
||||||
if(c->land == laOcean) {
|
if(c->land == laOcean) {
|
||||||
int t = c->landparam;
|
int t = c->landparam;
|
||||||
@ -2390,6 +2427,11 @@ void checkTide(cell *c) {
|
|||||||
if(isFire(c) && t >= tidalphase)
|
if(isFire(c) && t >= tidalphase)
|
||||||
c->wall = waSea;
|
c->wall = waSea;
|
||||||
}
|
}
|
||||||
|
if(isAlch2(c, true)) {
|
||||||
|
int id = alchemyval(c, 0);
|
||||||
|
if(id < 96) c->wall = waBubble;
|
||||||
|
else c->wall = waSlime1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildAirmap() {
|
void buildAirmap() {
|
||||||
@ -2746,6 +2788,7 @@ void bfs() {
|
|||||||
else if(isLeader(c2->monst)) havewhat |= HF_LEADER;
|
else if(isLeader(c2->monst)) havewhat |= HF_LEADER;
|
||||||
else if(c2->monst == moEarthElemental) havewhat |= HF_EARTH;
|
else if(c2->monst == moEarthElemental) havewhat |= HF_EARTH;
|
||||||
else if(c2->monst == moWaterElemental) havewhat |= HF_WATER;
|
else if(c2->monst == moWaterElemental) havewhat |= HF_WATER;
|
||||||
|
else if(c2->monst == moVoidBeast) havewhat |= HF_VOID;
|
||||||
else if(c2->monst == moShark || c2->monst == moCShark) havewhat |= HF_SHARK;
|
else if(c2->monst == moShark || c2->monst == moCShark) havewhat |= HF_SHARK;
|
||||||
else if(c2->monst == moAirElemental)
|
else if(c2->monst == moAirElemental)
|
||||||
havewhat |= HF_AIR, airmap.push_back(make_pair(c2,0));
|
havewhat |= HF_AIR, airmap.push_back(make_pair(c2,0));
|
||||||
@ -2878,6 +2921,14 @@ void destroyWeakBranch(cell *cf, cell *ct, eMonster who) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void activateArrowTrap(cell *c) {
|
||||||
|
if(c->wall == waArrowTrap && c->wparam == 0) {
|
||||||
|
c->wparam = 1;
|
||||||
|
forCellEx(c2, c) activateArrowTrap(c2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// effect of moving monster m from cf to ct
|
// effect of moving monster m from cf to ct
|
||||||
// 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)
|
||||||
@ -2893,6 +2944,9 @@ void moveEffect(cell *ct, cell *cf, eMonster m) {
|
|||||||
|
|
||||||
if((ct->wall == waClosePlate || ct->wall == waOpenPlate) && !ignoresPlates(m))
|
if((ct->wall == waClosePlate || ct->wall == waOpenPlate) && !ignoresPlates(m))
|
||||||
toggleGates(ct, ct->wall);
|
toggleGates(ct, ct->wall);
|
||||||
|
|
||||||
|
if(ct->wall == waArrowTrap && !ignoresPlates(m))
|
||||||
|
activateArrowTrap(ct);
|
||||||
|
|
||||||
if(cf && isPrincess(m)) princess::move(ct, cf);
|
if(cf && isPrincess(m)) princess::move(ct, cf);
|
||||||
|
|
||||||
@ -2961,6 +3015,9 @@ void playerMoveEffects(cell *c1, cell *c2) {
|
|||||||
if((c2->wall == waClosePlate || c2->wall == waOpenPlate) && !markOrb(itOrbAether))
|
if((c2->wall == waClosePlate || c2->wall == waOpenPlate) && !markOrb(itOrbAether))
|
||||||
toggleGates(c2, c2->wall);
|
toggleGates(c2, c2->wall);
|
||||||
|
|
||||||
|
if(c2->wall == waArrowTrap && !markOrb(itOrbAether))
|
||||||
|
activateArrowTrap(c2);
|
||||||
|
|
||||||
princess::playernear(c2);
|
princess::playernear(c2);
|
||||||
|
|
||||||
if(c2->wall == waGlass && items[itOrbAether] > ORBBASE+1) {
|
if(c2->wall == waGlass && items[itOrbAether] > ORBBASE+1) {
|
||||||
@ -3383,6 +3440,7 @@ int stayval(cell *c, flagtype mf) {
|
|||||||
if(isWorm(c->monst)) return 550;
|
if(isWorm(c->monst)) return 550;
|
||||||
if(c->monst == moRagingBull) return -1690; // worse than to stay in place
|
if(c->monst == moRagingBull) return -1690; // worse than to stay in place
|
||||||
if(c->monst == moBat && batsAfraid(c)) return 575;
|
if(c->monst == moBat && batsAfraid(c)) return 575;
|
||||||
|
if(c->monst == moHunterGuard) return 1600; // prefers to stay in place
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3423,8 +3481,11 @@ int determinizeBullPush(cellwalker bull) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int posdir[10], nc;
|
||||||
|
|
||||||
int pickMoveDirection(cell *c, flagtype mf) {
|
int pickMoveDirection(cell *c, flagtype mf) {
|
||||||
int posdir[10], nc = 0, bestval = stayval(c, mf);
|
int bestval = stayval(c, mf);
|
||||||
|
nc = 1; posdir[0] = -1;
|
||||||
|
|
||||||
// printf("stayval [%p, %s]: %d\n", c, dnameof(c->monst), bestval);
|
// printf("stayval [%p, %s]: %d\n", c, dnameof(c->monst), bestval);
|
||||||
for(int d=0; d<c->type; d++) {
|
for(int d=0; d<c->type; d++) {
|
||||||
@ -3439,8 +3500,7 @@ int pickMoveDirection(cell *c, flagtype mf) {
|
|||||||
determinizeBull(c, posdir, nc);
|
determinizeBull(c, posdir, nc);
|
||||||
|
|
||||||
if(!nc) return -1;
|
if(!nc) return -1;
|
||||||
nc = hrand(nc);
|
return posdir[hrand(nc)];
|
||||||
return posdir[nc];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pickDownDirection(cell *c, flagtype mf) {
|
int pickDownDirection(cell *c, flagtype mf) {
|
||||||
@ -3523,13 +3583,15 @@ void beastAttack(cell *c, bool player) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool quantum;
|
||||||
|
|
||||||
cell *moveNormal(cell *c, flagtype mf) {
|
cell *moveNormal(cell *c, flagtype mf) {
|
||||||
eMonster m = c->monst;
|
eMonster m = c->monst;
|
||||||
|
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
if(c->stuntime) {
|
if(c->stuntime) {
|
||||||
if(cellEdgeUnstable(c, MF_STUNNED)) d = pickDownDirection(c, mf);
|
if(cellEdgeUnstable(c, MF_STUNNED)) d = pickDownDirection(c, mf), nc = 1, posdir[0] = d;
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3541,24 +3603,55 @@ cell *moveNormal(cell *c, flagtype mf) {
|
|||||||
stayEffect(c);
|
stayEffect(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
cell *c2 = c->mov[d];
|
|
||||||
|
|
||||||
if(isPlayerOn(c2)) {
|
|
||||||
killThePlayerAt(m, c2, 0);
|
|
||||||
return c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
eMonster m2 = c2->monst;
|
|
||||||
if(m2) {
|
|
||||||
attackMonster(c2, AF_ORSTUN | AF_MSG, m);
|
|
||||||
if(m == moFlailer && m2 == moIllusion)
|
|
||||||
attackMonster(c, 0, m2);
|
|
||||||
return c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
moveMonster(c2, c);
|
if(!quantum) {
|
||||||
if(m == moRagingBull) beastAttack(c2, false);
|
cell *c2 = c->mov[d];
|
||||||
return c2;
|
if(isPlayerOn(c2)) {
|
||||||
|
killThePlayerAt(m, c2, 0);
|
||||||
|
return c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
eMonster m2 = c2->monst;
|
||||||
|
if(m2) {
|
||||||
|
attackMonster(c2, AF_ORSTUN | AF_MSG, m);
|
||||||
|
if(m == moFlailer && m2 == moIllusion)
|
||||||
|
attackMonster(c, 0, m2);
|
||||||
|
return c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveMonster(c2, c);
|
||||||
|
if(m == moRagingBull) beastAttack(c2, false);
|
||||||
|
return c2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool attacking = false;
|
||||||
|
for(int i=0; i<nc; i++) {
|
||||||
|
cell *c2 = c->mov[posdir[i]];
|
||||||
|
|
||||||
|
if(isPlayerOn(c2)) {
|
||||||
|
killThePlayerAt(m, c2, 0);
|
||||||
|
attacking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
eMonster m2 = c2->monst;
|
||||||
|
if(m2) {
|
||||||
|
attackMonster(c2, AF_ORSTUN | AF_MSG, m);
|
||||||
|
if(m == moFlailer && m2 == moIllusion)
|
||||||
|
attackMonster(c, 0, m2);
|
||||||
|
attacking = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!attacking) for(int i=0; i<nc; i++) {
|
||||||
|
cell *c2 = c->mov[posdir[i]];
|
||||||
|
if(!c->monst) c->monst = m;
|
||||||
|
moveMonster(c2, c);
|
||||||
|
if(m == moRagingBull) beastAttack(c2, false);
|
||||||
|
}
|
||||||
|
return c->mov[d];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void explodeAround(cell *c) {
|
void explodeAround(cell *c) {
|
||||||
@ -4136,8 +4229,9 @@ void snakeAttack(cell *c, bool mounted) {
|
|||||||
for(int j=0; j<c->type; j++)
|
for(int j=0; j<c->type; j++)
|
||||||
if(c->mov[j] && canAttack(c, moHexSnake, c->mov[j], c->mov[j]->monst,
|
if(c->mov[j] && canAttack(c, moHexSnake, c->mov[j], c->mov[j]->monst,
|
||||||
mounted ? AF_ONLY_ENEMY : (AF_ONLY_FBUG | AF_GETPLAYER))) {
|
mounted ? AF_ONLY_ENEMY : (AF_ONLY_FBUG | AF_GETPLAYER))) {
|
||||||
|
eMonster m2 = c->mov[j]->monst;
|
||||||
attackMonster(c->mov[j], AF_ORSTUN | AF_GETPLAYER | AF_MSG, moHexSnake);
|
attackMonster(c->mov[j], AF_ORSTUN | AF_GETPLAYER | AF_MSG, moHexSnake);
|
||||||
|
produceGhost(c->mov[j], moHexSnake, m2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4425,6 +4519,36 @@ void swordAttackStatic() {
|
|||||||
swordAttackStatic(bb);
|
swordAttackStatic(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sideAttack(cell *mf, int dir, eMonster who, int bonus, eItem orb) {
|
||||||
|
if(!items[orb]) return;
|
||||||
|
if(who != moPlayer && !items[itOrbEmpathy]) return;
|
||||||
|
for(int k: {-1, 1}) {
|
||||||
|
cell *mt = getMovR(mf, dir + k*bonus);
|
||||||
|
eMonster m = mt->monst;
|
||||||
|
if(canAttack(mf, who, mt, m, AF_SIDE)) {
|
||||||
|
markOrb(orb);
|
||||||
|
if(who != moPlayer) markOrb(itOrbEmpathy);
|
||||||
|
if(attackMonster(mt, AF_ORSTUN | AF_SIDE | AF_MSG, who))
|
||||||
|
produceGhost(mt, m, who);
|
||||||
|
}
|
||||||
|
else if(mt->wall == waBigTree)
|
||||||
|
mt->wall = waSmallTree;
|
||||||
|
else if(mt->wall == waSmallTree)
|
||||||
|
mt->wall = waNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) {
|
||||||
|
|
||||||
|
int k = tkills();
|
||||||
|
sideAttack(mf, dir, who, 1, itOrbSide1);
|
||||||
|
sideAttack(mf, dir, who, 2, itOrbSide2);
|
||||||
|
sideAttack(mf, dir, who, 3, itOrbSide3);
|
||||||
|
|
||||||
|
int kills = tkills() - k + bonuskill;
|
||||||
|
if(kills >= 5) achievement_gain("MELEE5");
|
||||||
|
}
|
||||||
|
|
||||||
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
|
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
|
||||||
int numsh = 0, numflail = 0, numlance = 0, numslash = 0;
|
int numsh = 0, numflail = 0, numlance = 0, numslash = 0;
|
||||||
|
|
||||||
@ -4685,6 +4809,7 @@ void movegolems(flagtype flags) {
|
|||||||
}
|
}
|
||||||
attackMonster(c2, ((revenge||jealous)?0:AF_ORSTUN) | AF_MSG, m);
|
attackMonster(c2, ((revenge||jealous)?0:AF_ORSTUN) | AF_MSG, m);
|
||||||
produceGhost(c2, m2, m);
|
produceGhost(c2, m2, m);
|
||||||
|
sideAttack(c, dir, m, 0);
|
||||||
if(revenge) c->monst = m = moPrincessArmed;
|
if(revenge) c->monst = m = moPrincessArmed;
|
||||||
if(jealous) {
|
if(jealous) {
|
||||||
playSound(c2, princessgender() ? "dzia-princess" : "dzia-prince");
|
playSound(c2, princessgender() ? "dzia-princess" : "dzia-prince");
|
||||||
@ -4960,7 +5085,7 @@ void moverefresh(bool turn = true) {
|
|||||||
if(c->monst == moTortoise && c->item == itBabyTortoise &&
|
if(c->monst == moTortoise && c->item == itBabyTortoise &&
|
||||||
!((tortoise::getb(c) ^ tortoise::babymap[c]) & tortoise::mask))
|
!((tortoise::getb(c) ^ tortoise::babymap[c]) & tortoise::mask))
|
||||||
c->stuntime = 2;
|
c->stuntime = 2;
|
||||||
|
|
||||||
if(c->monst == moReptile) {
|
if(c->monst == moReptile) {
|
||||||
if(c->wall == waChasm || cellUnstable(c)) {
|
if(c->wall == waChasm || cellUnstable(c)) {
|
||||||
c->monst = moNone;
|
c->monst = moNone;
|
||||||
@ -5166,6 +5291,8 @@ void movemonsters() {
|
|||||||
if(havewhat & HF_EARTH) groupmove(moEarthElemental, 0);
|
if(havewhat & HF_EARTH) groupmove(moEarthElemental, 0);
|
||||||
DEBT("water");
|
DEBT("water");
|
||||||
if(havewhat & HF_WATER) groupmove(moWaterElemental, 0);
|
if(havewhat & HF_WATER) groupmove(moWaterElemental, 0);
|
||||||
|
DEBT("void");
|
||||||
|
if(havewhat & HF_VOID) groupmove(moVoidBeast, 0);
|
||||||
DEBT("leader");
|
DEBT("leader");
|
||||||
if(havewhat & HF_LEADER) groupmove(moPirate, 0);
|
if(havewhat & HF_LEADER) groupmove(moPirate, 0);
|
||||||
DEBT("mutant");
|
DEBT("mutant");
|
||||||
@ -5717,6 +5844,140 @@ void collectMessage(cell *c2, eItem which) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ambushval;
|
||||||
|
|
||||||
|
void ambush(cell *c, eItem what) {
|
||||||
|
int maxdist = purehepta ? 5 : 7;
|
||||||
|
celllister cl(c, maxdist, 1000000, NULL);
|
||||||
|
cell *c0 = c;
|
||||||
|
int d = 0;
|
||||||
|
cl.prepare();
|
||||||
|
bool restricted = false;
|
||||||
|
for(cell *cx: cl.lst) {
|
||||||
|
int dh = cl.getdist(cx);
|
||||||
|
if(dh <= 2 && cx->monst == moHunterGuard)
|
||||||
|
cx->monst = moHunterDog;
|
||||||
|
if(dh <= 3 && cx->monst) restricted = true;
|
||||||
|
if(dh > d) c0 = cx, d = dh;
|
||||||
|
}
|
||||||
|
vector<cell*> around;
|
||||||
|
cell *clast = NULL;
|
||||||
|
cell *ccur = c0;
|
||||||
|
while(true) {
|
||||||
|
cell *c2 = NULL;
|
||||||
|
forCellEx(c1, ccur)
|
||||||
|
if(c1 != clast && cl.listed(c1) && cl.getdist(c1) == d)
|
||||||
|
c2 = c1;
|
||||||
|
if(!c2) break;
|
||||||
|
if(c2->land == laDogPlains && c2->wall == waNone && c2->monst == moNone)
|
||||||
|
around.push_back(c2);
|
||||||
|
clast = ccur; ccur = c2;
|
||||||
|
if(c2 == c0) break;
|
||||||
|
}
|
||||||
|
int N = size(around);
|
||||||
|
int dogs;
|
||||||
|
|
||||||
|
int qty = items[itDogPlains];
|
||||||
|
|
||||||
|
if(ambushval) dogs = ambushval;
|
||||||
|
else
|
||||||
|
switch(what) {
|
||||||
|
case itDogPlains:
|
||||||
|
if(qty <= 16)
|
||||||
|
dogs = qty;
|
||||||
|
else
|
||||||
|
dogs = max(33-qty, 6);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbSide3:
|
||||||
|
dogs = restricted ? 10 : 20;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbFreedom:
|
||||||
|
dogs = restricted ? 10 : 60;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbThorns:
|
||||||
|
case itOrb37:
|
||||||
|
dogs = 20;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case itOrbBeauty:
|
||||||
|
dogs = 35;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case itOrbShell:
|
||||||
|
dogs = 35;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbPsi:
|
||||||
|
// dogs = 40; -> no benefits
|
||||||
|
dogs = 20;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbDash:
|
||||||
|
case itOrbFrog:
|
||||||
|
dogs = 40;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbAir:
|
||||||
|
case itOrbDragon:
|
||||||
|
dogs = 50;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbStunning:
|
||||||
|
// dogs = restricted ? 50 : 60; -> no benefits
|
||||||
|
dogs = 30;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbBull:
|
||||||
|
case itOrbSpeed:
|
||||||
|
case itOrbShield:
|
||||||
|
dogs = 60;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbInvis:
|
||||||
|
dogs = 80;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itOrbTeleport:
|
||||||
|
dogs = 300;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itGreenStone:
|
||||||
|
case itOrbSafety:
|
||||||
|
case itOrbYendor:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case itKey:
|
||||||
|
dogs = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case itWarning:
|
||||||
|
dogs = qty;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dogs = restricted ? 6 : 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Flash can survive about 70, but this gives no benefits
|
||||||
|
}
|
||||||
|
|
||||||
|
int gaps = dogs;
|
||||||
|
if(!N) return;
|
||||||
|
int shift = hrand(N);
|
||||||
|
dogs = min(dogs, N);
|
||||||
|
gaps = min(gaps, N);
|
||||||
|
for(int i=0; i<dogs; i++) {
|
||||||
|
int pos = (shift + (N * i) / gaps) % N;
|
||||||
|
cell *nextdog = around[pos];
|
||||||
|
nextdog->monst = moHunterDog;
|
||||||
|
nextdog->stuntime = 1;
|
||||||
|
drawFlash(nextdog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool collectItem(cell *c2, bool telekinesis) {
|
bool collectItem(cell *c2, bool telekinesis) {
|
||||||
|
|
||||||
int pg = gold();
|
int pg = gold();
|
||||||
@ -5739,6 +6000,11 @@ bool collectItem(cell *c2, bool telekinesis) {
|
|||||||
if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item);
|
if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item);
|
||||||
if(c2->item == itDodeca && peace::on) peace::simon::extend();
|
if(c2->item == itDodeca && peace::on) peace::simon::extend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c2->land == laDogPlains && c2->item) {
|
||||||
|
addMessage(XLAT("You are ambushed!"));
|
||||||
|
ambush(c2, c2->item);
|
||||||
|
}
|
||||||
|
|
||||||
if(isRevivalOrb(c2->item) && multi::revive_queue.size()) {
|
if(isRevivalOrb(c2->item) && multi::revive_queue.size()) {
|
||||||
multiRevival(cwt.c, c2);
|
multiRevival(cwt.c, c2);
|
||||||
@ -5874,7 +6140,7 @@ bool collectItem(cell *c2, bool telekinesis) {
|
|||||||
gainItem(itElemental);
|
gainItem(itElemental);
|
||||||
gainItem(itElemental);
|
gainItem(itElemental);
|
||||||
addMessage(XLAT("You construct some Elemental Gems!", c2->item) + itemcounter(items[itElemental]));
|
addMessage(XLAT("You construct some Elemental Gems!", c2->item) + itemcounter(items[itElemental]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(c2->item == itBounty)
|
if(c2->item == itBounty)
|
||||||
items[itRevolver] = 6;
|
items[itRevolver] = 6;
|
||||||
@ -6199,6 +6465,19 @@ namespace orbbull {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void terracotta() {
|
||||||
|
for(int i=0; i<numplayers(); i++)
|
||||||
|
forCellEx(c2, playerpos(i))
|
||||||
|
if(c2->wall == waTerraWarrior) {
|
||||||
|
c2->landparam++;
|
||||||
|
if((c2->landparam == 3 && hrand(3) == 0) ||
|
||||||
|
(c2->landparam == 4 && hrand(2) == 0) ||
|
||||||
|
c2->landparam == 5)
|
||||||
|
c2->monst = moTerraWarrior,
|
||||||
|
c2->wall = waNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void monstersTurn() {
|
void monstersTurn() {
|
||||||
mirror::breakAll();
|
mirror::breakAll();
|
||||||
DEBT("bfs");
|
DEBT("bfs");
|
||||||
@ -6239,7 +6518,8 @@ void monstersTurn() {
|
|||||||
|
|
||||||
orbbull::check();
|
orbbull::check();
|
||||||
|
|
||||||
|
terracotta();
|
||||||
|
|
||||||
DEBT("check");
|
DEBT("check");
|
||||||
checkmove();
|
checkmove();
|
||||||
if(canmove) elec::checklightningfast();
|
if(canmove) elec::checklightningfast();
|
||||||
@ -6559,16 +6839,19 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
addMessage(XLAT("You start chopping down the tree."));
|
addMessage(XLAT("You start chopping down the tree."));
|
||||||
playSound(c2, "hit-axe" + pick123());
|
playSound(c2, "hit-axe" + pick123());
|
||||||
c2->wall = waNone;
|
c2->wall = waNone;
|
||||||
|
sideAttack(cwt.c, d, moPlayer, 0);
|
||||||
}
|
}
|
||||||
else if(c2->wall == waBigTree) {
|
else if(c2->wall == waBigTree) {
|
||||||
drawParticles(c2, winf[c2->wall].color, 8);
|
drawParticles(c2, winf[c2->wall].color, 8);
|
||||||
addMessage(XLAT("You chop down the tree."));
|
addMessage(XLAT("You chop down the tree."));
|
||||||
playSound(c2, "hit-axe" + pick123());
|
playSound(c2, "hit-axe" + pick123());
|
||||||
c2->wall = waSmallTree;
|
sideAttack(cwt.c, d, moPlayer, 0);
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(survivalist && isHaunted(c2->land))
|
if(survivalist && isHaunted(c2->land))
|
||||||
survivalist = false;
|
survivalist = false;
|
||||||
@ -6692,6 +6975,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sideAttack(cwt.c, d, moPlayer, 0);
|
||||||
lastmovetype = lmAttack; lastmove = c2;
|
lastmovetype = lmAttack; lastmove = c2;
|
||||||
swordAttackStatic();
|
swordAttackStatic();
|
||||||
}
|
}
|
||||||
|
166
graph.cpp
166
graph.cpp
@ -403,9 +403,8 @@ void ShadowV(const transmatrix& V, const hpcshape& bp, int prio) {
|
|||||||
if(mmspatial) {
|
if(mmspatial) {
|
||||||
if(pmodel == mdHyperboloid || pmodel == mdBall)
|
if(pmodel == mdHyperboloid || pmodel == mdBall)
|
||||||
return; // shadows break the depth testing
|
return; // shadows break the depth testing
|
||||||
int p = poly_outline; poly_outline = OUTLINE_TRANS;
|
dynamicval<int> p(poly_outline, OUTLINE_TRANS);
|
||||||
queuepolyat(V, bp, SHADOW_MON, prio);
|
queuepolyat(V, bp, SHADOW_MON, prio);
|
||||||
poly_outline = p;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,6 +502,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
|
|||||||
it == itHolyGrail ? &shGrail :
|
it == itHolyGrail ? &shGrail :
|
||||||
isElementalShard(it) ? &shElementalShard :
|
isElementalShard(it) ? &shElementalShard :
|
||||||
(it == itBombEgg || it == itTrollEgg) ? &shEgg :
|
(it == itBombEgg || it == itTrollEgg) ? &shEgg :
|
||||||
|
it == itDogPlains ? &shTriangle :
|
||||||
it == itDodeca ? &shDodeca :
|
it == itDodeca ? &shDodeca :
|
||||||
xch == '*' ? &shGem[ct6] :
|
xch == '*' ? &shGem[ct6] :
|
||||||
it == itShard ? &shMFloor[0] :
|
it == itShard ? &shMFloor[0] :
|
||||||
@ -610,8 +610,12 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
|
|||||||
|
|
||||||
if(xsh == &shBookCover && mmitem)
|
if(xsh == &shBookCover && mmitem)
|
||||||
queuepoly(V2, shBook, 0x805020FF);
|
queuepoly(V2, shBook, 0x805020FF);
|
||||||
|
|
||||||
|
int pr = PPR_ITEM;
|
||||||
|
int alpha = hidden ? (it == itKraken ? 0xC0 : 0x40) : 0xF0;
|
||||||
|
if(c && c->wall == waIcewall) pr = PPR_HIDDEN, alpha = 0x80;
|
||||||
|
|
||||||
queuepoly(V2, *xsh, darkena(icol, 0, hidden ? (it == itKraken ? 0xC0 : 0x40) : 0xF0));
|
queuepolyat(V2, *xsh, darkena(icol, 0, alpha), pr);
|
||||||
|
|
||||||
if(it == itZebra)
|
if(it == itZebra)
|
||||||
queuepolyat(V * spin(ticks / 1500. + M_PI/(ct6+6)), *xsh, darkena(0x202020, 0, hidden ? 0x40 : 0xF0), PPR_ITEMb);
|
queuepolyat(V * spin(ticks / 1500. + M_PI/(ct6+6)), *xsh, darkena(0x202020, 0, hidden ? 0x40 : 0xF0), PPR_ITEMb);
|
||||||
@ -645,6 +649,17 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawTerraWarrior(const transmatrix& V, int t, double footphase) {
|
||||||
|
int col = 0xC0C0C0;
|
||||||
|
int col2 = t > 6 ? 0x4040C0 : 0x6060A0;
|
||||||
|
ShadowV(V, shPBody);
|
||||||
|
otherbodyparts(V, darkena(t > 4 ? col2 : col, 0, 0xF0), moDesertman, footphase);
|
||||||
|
queuepoly(VBODY, shPBody, darkena(t > 0 ? col2 : col, 0, 0xF0));
|
||||||
|
queuepoly(VBODY, shPrinceDress, darkena(t > 1 ? col2 : col, 0, 0xF0));
|
||||||
|
if(!peace::on) queuepoly(VBODY * Mirror, shPSword, darkena(t > 2 ? col2 : col, 0, 0xF0));
|
||||||
|
queuepoly(VHEAD, shTurban1, darkena(t > 3 ? col2 : col, 0, 0xF0));
|
||||||
|
}
|
||||||
|
|
||||||
bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, double footphase) {
|
bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, double footphase) {
|
||||||
|
|
||||||
char xch = minf[m].glyph;
|
char xch = minf[m].glyph;
|
||||||
@ -984,7 +999,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
}
|
}
|
||||||
queuepoly(VABODY, shBugArmor, darkena(col, 1, 0xFF));
|
queuepoly(VABODY, shBugArmor, darkena(col, 1, 0xFF));
|
||||||
}
|
}
|
||||||
else if(m == moRunDog) {
|
else if(m == moRunDog || m == moHunterDog || m == moHunterGuard) {
|
||||||
if(!mmspatial && !footphase)
|
if(!mmspatial && !footphase)
|
||||||
queuepoly(VABODY, shDogBody, darkena(col, 0, 0xFF));
|
queuepoly(VABODY, shDogBody, darkena(col, 0, 0xFF));
|
||||||
else {
|
else {
|
||||||
@ -993,9 +1008,18 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
animallegs(VALEGS, moRunDog, darkena(col, 0, 0xFF), footphase);
|
animallegs(VALEGS, moRunDog, darkena(col, 0, 0xFF), footphase);
|
||||||
}
|
}
|
||||||
queuepoly(VAHEAD, shDogHead, darkena(col, 0, 0xFF));
|
queuepoly(VAHEAD, shDogHead, darkena(col, 0, 0xFF));
|
||||||
queuepoly(VAHEAD, shWolf1, darkena(0x202020, 0, 0xFF));
|
|
||||||
queuepoly(VAHEAD, shWolf2, darkena(0x202020, 0, 0xFF));
|
{
|
||||||
queuepoly(VAHEAD, shWolf3, darkena(0x202020, 0, 0xFF));
|
dynamicval<int> dp(poly_outline);
|
||||||
|
dynamicval<double> dw(minwidth_global);
|
||||||
|
bool redeyes = m != moRunDog;
|
||||||
|
int eyes = darkena(redeyes ? 0xFF0000 : 0x202020, 0, 0xFF);
|
||||||
|
|
||||||
|
if(redeyes) poly_outline = eyes, minwidth_global = 1;
|
||||||
|
queuepoly(VAHEAD, shWolf1, eyes);
|
||||||
|
queuepoly(VAHEAD, shWolf2, eyes);
|
||||||
|
}
|
||||||
|
queuepoly(VAHEAD, shWolf3, darkena(m == moRunDog ? 0x202020 : 0x000000, 0, 0xFF));
|
||||||
}
|
}
|
||||||
else if(m == moOrangeDog) {
|
else if(m == moOrangeDog) {
|
||||||
if(!mmspatial && !footphase)
|
if(!mmspatial && !footphase)
|
||||||
@ -1014,7 +1038,8 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
else if(m == moShark || m == moGreaterShark || m == moCShark)
|
else if(m == moShark || m == moGreaterShark || m == moCShark)
|
||||||
queuepoly(VFISH, shShark, darkena(col, 0, 0xFF));
|
queuepoly(VFISH, shShark, darkena(col, 0, 0xFF));
|
||||||
else if(m == moEagle || m == moParrot || m == moBomberbird || m == moAlbatross ||
|
else if(m == moEagle || m == moParrot || m == moBomberbird || m == moAlbatross ||
|
||||||
m == moTameBomberbird || m == moWindCrow || m == moTameBomberbirdMoved) {
|
m == moTameBomberbird || m == moWindCrow || m == moTameBomberbirdMoved ||
|
||||||
|
m == moSandBird) {
|
||||||
ShadowV(V, shEagle);
|
ShadowV(V, shEagle);
|
||||||
queuepoly(VBIRD, shEagle, darkena(col, 0, 0xFF));
|
queuepoly(VBIRD, shEagle, darkena(col, 0, 0xFF));
|
||||||
}
|
}
|
||||||
@ -1062,6 +1087,8 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
ShadowV(V, shPBody);
|
ShadowV(V, shPBody);
|
||||||
queuepoly(VBODY, shPBody, c);
|
queuepoly(VBODY, shPBody, c);
|
||||||
}
|
}
|
||||||
|
else if(m == moTerraWarrior)
|
||||||
|
drawTerraWarrior(V, 7, footphase);
|
||||||
else if(m == moDesertman) {
|
else if(m == moDesertman) {
|
||||||
otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase);
|
otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase);
|
||||||
ShadowV(V, shPBody);
|
ShadowV(V, shPBody);
|
||||||
@ -1180,6 +1207,15 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
queuepoly(VHEAD, shPFace, darkena(col, 1, 0x90));
|
queuepoly(VHEAD, shPFace, darkena(col, 1, 0x90));
|
||||||
queuepoly(VHEAD, shArmor, darkena(col, 0, 0xC0));
|
queuepoly(VHEAD, shArmor, darkena(col, 0, 0xC0));
|
||||||
}
|
}
|
||||||
|
else if(m == moTerraWarrior || m == moMercuryGuy || m == moLemur) {
|
||||||
|
ShadowV(V, shPBody);
|
||||||
|
otherbodyparts(V, darkena(col, 0, 0xF0), m, footphase);
|
||||||
|
queuepoly(VBODY, shPBody, darkena(col, 0, 0xF0));
|
||||||
|
if(!peace::on) queuepoly(VBODY * Mirror, shPSword, darkena(col, 0, 0xF0));
|
||||||
|
queuepoly(VHEAD, shPHead, darkena(col, 1, 0xF0));
|
||||||
|
queuepoly(VHEAD, shPFace, darkena(col, 1, 0xF0));
|
||||||
|
queuepoly(VHEAD, shArmor, darkena(col, 0, 0xF0));
|
||||||
|
}
|
||||||
else if(m == moGhost || m == moSeep || m == moFriendlyGhost) {
|
else if(m == moGhost || m == moSeep || m == moFriendlyGhost) {
|
||||||
if(m == moFriendlyGhost) col = fghostcolor(ticks, where);
|
if(m == moFriendlyGhost) col = fghostcolor(ticks, where);
|
||||||
queuepoly(VGHOST, shGhost, darkena(col, 0, m == moFriendlyGhost ? 0xC0 : 0x80));
|
queuepoly(VGHOST, shGhost, darkena(col, 0, m == moFriendlyGhost ? 0xC0 : 0x80));
|
||||||
@ -1285,6 +1321,12 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
if(b > 6) b = 6;
|
if(b > 6) b = 6;
|
||||||
queuepoly(VHEAD, shWightCloak, 0x605040A0 + 0x10101000 * b);
|
queuepoly(VHEAD, shWightCloak, 0x605040A0 + 0x10101000 * b);
|
||||||
}
|
}
|
||||||
|
else if(m == moVoidBeast) {
|
||||||
|
otherbodyparts(V, 0x080808D0, m, footphase);
|
||||||
|
queuepoly(VBODY, shPBody, 0x080808D0);
|
||||||
|
queuepoly(VHEAD, shPHead, 0x080808D0);
|
||||||
|
queuepoly(VHEAD, shWightCloak, 0xFF0000A0);
|
||||||
|
}
|
||||||
else if(m == moGoblin) {
|
else if(m == moGoblin) {
|
||||||
otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase);
|
otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase);
|
||||||
ShadowV(V, shYeti);
|
ShadowV(V, shYeti);
|
||||||
@ -1386,7 +1428,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
|||||||
int acol = col;
|
int acol = col;
|
||||||
queuepoly(VAHEAD, shTrylobiteHead, darkena(acol, 0, 0xFF));
|
queuepoly(VAHEAD, shTrylobiteHead, darkena(acol, 0, 0xFF));
|
||||||
}
|
}
|
||||||
else if(m == moEvilGolem) {
|
else if(m == moEvilGolem || m == moIceGolem) {
|
||||||
otherbodyparts(V, darkena(col, 2, 0xC0), m, footphase);
|
otherbodyparts(V, darkena(col, 2, 0xC0), m, footphase);
|
||||||
ShadowV(V, shPBody);
|
ShadowV(V, shPBody);
|
||||||
queuepoly(VBODY, shPBody, darkena(col, 0, 0XC0));
|
queuepoly(VBODY, shPBody, darkena(col, 0, 0XC0));
|
||||||
@ -2271,7 +2313,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
if(isWateryOrBoat(c) || c->wall == waReptileBridge) {
|
if(isWateryOrBoat(c) || c->wall == waReptileBridge) {
|
||||||
if(c->land == laOcean)
|
if(c->land == laOcean)
|
||||||
fcol = (c->landparam > 25 && !chaosmode) ? (
|
fcol = (c->landparam > 25 && !chaosmode) ? (
|
||||||
0x90 + 8 * sin(windmap::windcodes[windmap::getId(c)] * M_PI / 128 - SDL_GetTicks()/1000.)
|
0x90 + 8 * sin(windmap::windcodes[windmap::getId(c)] * M_PI / 128 - ticks/1000.)
|
||||||
) :
|
) :
|
||||||
0x1010C0 + int(32 * sin(ticks / 500. + (chaosmode ? c->CHAOSPARAM : c->landparam)*1.5));
|
0x1010C0 + int(32 * sin(ticks / 500. + (chaosmode ? c->CHAOSPARAM : c->landparam)*1.5));
|
||||||
else if(c->land == laOceanWall)
|
else if(c->land == laOceanWall)
|
||||||
@ -2366,11 +2408,6 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
case laCanvas:
|
case laCanvas:
|
||||||
fcol = c->landparam;
|
fcol = c->landparam;
|
||||||
break;
|
break;
|
||||||
case laAlchemy2:
|
|
||||||
fcol = (windmap::windcodes[windmap::getId(c)] - SDL_GetTicks()/10) & 255;
|
|
||||||
if(fcol > 128) fcol = 256 - fcol;
|
|
||||||
fcol += 96;
|
|
||||||
break;
|
|
||||||
case laPalace:
|
case laPalace:
|
||||||
fcol = 0x806020;
|
fcol = 0x806020;
|
||||||
if(c->wall == waClosedGate || c->wall == waOpenGate)
|
if(c->wall == waClosedGate || c->wall == waOpenGate)
|
||||||
@ -2422,6 +2459,17 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
fcol = wcol[whirlwind::fzebra3(c)];
|
fcol = wcol[whirlwind::fzebra3(c)];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case laDogPlains:
|
||||||
|
// fcol = pseudohept(c) ? 0x205050 : 0x306060;
|
||||||
|
fcol = 0x40E0D0;
|
||||||
|
fcol /= 2;
|
||||||
|
if(pseudohept(c)) fcol = fcol * 3/4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case laTerracotta:
|
||||||
|
fcol = 0x909090;
|
||||||
|
break;
|
||||||
|
|
||||||
case laIvoryTower:
|
case laIvoryTower:
|
||||||
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
||||||
@ -2492,24 +2540,34 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case laIce: case laCocytus:
|
case laIce: case laCocytus: case laBlizzard:
|
||||||
if(isIcyWall(c)) {
|
if(isIcyWall(c)) {
|
||||||
float h = HEAT(c);
|
float h = HEAT(c);
|
||||||
bool showcoc = c->land == laCocytus && chaosmode && !wmescher;
|
bool showcoc = c->land == laCocytus && chaosmode && !wmescher;
|
||||||
if(h < -0.4)
|
|
||||||
wcol = gradient(showcoc ? 0x4080FF : 0x4040FF, 0x0000FF, -0.4, h, -1);
|
int colorN04 = showcoc ? 0x4080FF : 0x4040FF;
|
||||||
|
int colorN10 = 0x0000FF;
|
||||||
|
int color0 = c->land == laBlizzard ? 0x5050C0 : showcoc ? 0x80C0FF : 0x8080FF;
|
||||||
|
int color02 = 0xFFFFFF;
|
||||||
|
int color06 = 0xFF0000;
|
||||||
|
int color08 = 0xFFFF00;
|
||||||
|
|
||||||
|
if(h < -1)
|
||||||
|
wcol = colorN10;
|
||||||
|
else if(h < -0.4)
|
||||||
|
wcol = gradient(colorN04, colorN10 , -0.4, h, -1);
|
||||||
else if(h < 0)
|
else if(h < 0)
|
||||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, showcoc ? 0x4080FF : 0x4040FF, 0, h, -0.4);
|
wcol = gradient(color0, colorN04, 0, h, -0.4);
|
||||||
else if(h < 0.2)
|
else if(h < 0.2)
|
||||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, 0xFFFFFF, 0, h, 0.2);
|
wcol = gradient(color0, color02, 0, h, 0.2);
|
||||||
// else if(h < 0.4)
|
// else if(h < 0.4)
|
||||||
// wcol = gradient(0xFFFFFF, 0xFFFF00, 0.2, h, 0.4);
|
// wcol = gradient(0xFFFFFF, 0xFFFF00, 0.2, h, 0.4);
|
||||||
else if(h < 0.6)
|
else if(h < 0.6)
|
||||||
wcol = gradient(0xFFFFFF, 0xFF0000, 0.2, h, 0.6);
|
wcol = gradient(color02, color06, 0.2, h, 0.6);
|
||||||
else if(h < 0.8)
|
else if(h < 0.8)
|
||||||
wcol = gradient(0xFF0000, 0xFFFF00, 0.6, h, 0.8);
|
wcol = gradient(color06, color08, 0.6, h, 0.8);
|
||||||
else
|
else
|
||||||
wcol = 0xFFFF00;
|
wcol = color08;
|
||||||
if(c->wall == waFrozenLake)
|
if(c->wall == waFrozenLake)
|
||||||
fcol = wcol;
|
fcol = wcol;
|
||||||
else
|
else
|
||||||
@ -2563,6 +2621,15 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
else
|
else
|
||||||
fcol = wcol;
|
fcol = wcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isAlch2(c, true)) {
|
||||||
|
int id = alchemyval(c, -1);
|
||||||
|
if(id < 96)
|
||||||
|
wcol = gradient(0x800000, 0xFF0000, 0, id, 96);
|
||||||
|
else
|
||||||
|
wcol = gradient(0x00FF00, 0xFFFF00, 96, id, 255);
|
||||||
|
fcol = wcol;
|
||||||
|
}
|
||||||
|
|
||||||
if(c->wall == waDeadTroll2 || c->wall == waPetrified || c->wall == waPetrifiedBridge) {
|
if(c->wall == waDeadTroll2 || c->wall == waPetrified || c->wall == waPetrifiedBridge) {
|
||||||
eMonster m = eMonster(c->wparam);
|
eMonster m = eMonster(c->wparam);
|
||||||
@ -2884,6 +2951,8 @@ bool allemptynear(cell *c) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "blizzard.cpp"
|
||||||
|
|
||||||
void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||||
|
|
||||||
qfi.shape = NULL; qfi.special = false;
|
qfi.shape = NULL; qfi.special = false;
|
||||||
@ -3160,7 +3229,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
int fd =
|
int fd =
|
||||||
c->land == laRedRock ? 0 :
|
c->land == laRedRock ? 0 :
|
||||||
(c->land == laOcean || c->land == laLivefjord || c->land == laWhirlpool) ? 1 :
|
(c->land == laOcean || c->land == laLivefjord || c->land == laWhirlpool) ? 1 :
|
||||||
c->land == laAlchemist || c->land == laIce || c->land == laGraveyard ||
|
c->land == laAlchemist || c->land == laIce || c->land == laGraveyard || c->land == laBlizzard ||
|
||||||
c->land == laRlyeh || c->land == laTemple || c->land == laWineyard ||
|
c->land == laRlyeh || c->land == laTemple || c->land == laWineyard ||
|
||||||
c->land == laDeadCaves || c->land == laPalace || c->land == laCA ? 1 :
|
c->land == laDeadCaves || c->land == laPalace || c->land == laCA ? 1 :
|
||||||
c->land == laCanvas ? 0 :
|
c->land == laCanvas ? 0 :
|
||||||
@ -3179,7 +3248,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
c->land == laHalloween ? 1 :
|
c->land == laHalloween ? 1 :
|
||||||
c->land == laTrollheim ? 2 :
|
c->land == laTrollheim ? 2 :
|
||||||
c->land == laReptile ? 0 :
|
c->land == laReptile ? 0 :
|
||||||
|
c->land == laDogPlains ? 1 :
|
||||||
2;
|
2;
|
||||||
|
|
||||||
|
if(c->land == laAlchemy2) {
|
||||||
|
int id = alchemyval(c, -1);
|
||||||
|
if(id/4 == 95/4 || id/4 == 255/4) fd = 0;
|
||||||
|
if(id/4 == 95/4-1 || id/4 == 255/4-1) fd = 1;
|
||||||
|
}
|
||||||
|
|
||||||
poly_outline = OUTLINE_DEFAULT;
|
poly_outline = OUTLINE_DEFAULT;
|
||||||
|
|
||||||
@ -3360,6 +3436,11 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
else if(wmblack == 1 && c->wall == waMineOpen && vid.grid)
|
else if(wmblack == 1 && c->wall == waMineOpen && vid.grid)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// else if(true)
|
||||||
|
// qfloor(c, Vf, shWave[wavephase][ct6], darkena(fcol, fd, 0xFF));
|
||||||
|
// else if(true)
|
||||||
|
// qfloor(c, Vf, shSeabed[ct6], darkena(fcol, fd, 0xFF));
|
||||||
|
|
||||||
else if(wmblack) {
|
else if(wmblack) {
|
||||||
qfloor(c, Vf, shBFloor[ct6], darkena(fcol, 0, 0xFF));
|
qfloor(c, Vf, shBFloor[ct6], darkena(fcol, 0, 0xFF));
|
||||||
int rd = rosedist(c);
|
int rd = rosedist(c);
|
||||||
@ -3505,7 +3586,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
else if(c->land == laHell)
|
else if(c->land == laHell)
|
||||||
qfloor(c, Vf, (euclid ? shStarFloor : shDemonFloor)[ct6], darkena(fcol, fd, 0xFF));
|
qfloor(c, Vf, (euclid ? shStarFloor : shDemonFloor)[ct6], darkena(fcol, fd, 0xFF));
|
||||||
|
|
||||||
else if(c->land == laIce)
|
else if(c->land == laIce || c->land == laBlizzard)
|
||||||
qfloor(c, Vf, shStarFloor[ct6], darkena(fcol, fd, 0xFF));
|
qfloor(c, Vf, shStarFloor[ct6], darkena(fcol, fd, 0xFF));
|
||||||
|
|
||||||
else if(c->land == laCocytus)
|
else if(c->land == laCocytus)
|
||||||
@ -3680,8 +3761,11 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
placeSidewallX(c, i, SIDE_LAKE, V, isWarped(c), false, darkena(gradient(0, col, 0, .8, 1), fd, 0xFF));
|
placeSidewallX(c, i, SIDE_LAKE, V, isWarped(c), false, darkena(gradient(0, col, 0, .8, 1), fd, 0xFF));
|
||||||
chasmg = 1;
|
chasmg = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c->wall == waTerraWarrior)
|
||||||
|
drawTerraWarrior(V, c->landparam & 7, 0);
|
||||||
|
|
||||||
if(c->wall == waBoat || c->wall == waStrandedBoat) {
|
else if(c->wall == waBoat || c->wall == waStrandedBoat) {
|
||||||
double footphase;
|
double footphase;
|
||||||
bool magical = items[itOrbWater] && (isPlayerOn(c) || (isFriendly(c) && items[itOrbEmpathy]));
|
bool magical = items[itOrbWater] && (isPlayerOn(c) || (isFriendly(c) && items[itOrbEmpathy]));
|
||||||
int outcol = magical ? watercolor(0) : 0xC06000FF;
|
int outcol = magical ? watercolor(0) : 0xC06000FF;
|
||||||
@ -3741,7 +3825,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
|
|
||||||
else if(c->wall == waFrozenLake || c->wall == waLake || c->wall == waCamelotMoat ||
|
else if(c->wall == waFrozenLake || c->wall == waLake || c->wall == waCamelotMoat ||
|
||||||
c->wall == waSea || c->wall == waClosePlate || c->wall == waOpenPlate ||
|
c->wall == waSea || c->wall == waClosePlate || c->wall == waOpenPlate ||
|
||||||
c->wall == waOpenGate || c->wall == waTrapdoor)
|
c->wall == waOpenGate || c->wall == waTrapdoor || c->wall == waBubble)
|
||||||
;
|
;
|
||||||
|
|
||||||
else if(c->wall == waRose) {
|
else if(c->wall == waRose) {
|
||||||
@ -3837,32 +3921,35 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
transmatrix Vdepth = mscale(V, geom3::WALL);
|
transmatrix Vdepth = mscale(V, geom3::WALL);
|
||||||
|
int alpha = 0xFF;
|
||||||
|
if(c->wall == waIcewall)
|
||||||
|
alpha = 0xC0;
|
||||||
|
|
||||||
bool warp = isWarped(c);
|
bool warp = isWarped(c);
|
||||||
|
|
||||||
if(starcol && !(wmescher && c->wall == waPlatform))
|
if(starcol && !(wmescher && c->wall == waPlatform))
|
||||||
queuepolyat(Vdepth, shThisWall, darkena(starcol, 0, 0xFF), PPR_WALL3A);
|
queuepolyat(Vdepth, shThisWall, darkena(starcol, 0, 0xFF), PPR_WALL3A);
|
||||||
|
|
||||||
warpfloor(c, Vdepth, darkena(wcol0, fd, 0xFF), PPR_WALL3, warp);
|
warpfloor(c, Vdepth, darkena(wcol0, fd, alpha), PPR_WALL3, warp);
|
||||||
floorShadow(c, V, SHADOW_WALL, warp);
|
floorShadow(c, V, SHADOW_WALL, warp);
|
||||||
|
|
||||||
if(c->wall == waCamelot) {
|
if(c->wall == waCamelot) {
|
||||||
forCellIdEx(c2, i, c) {
|
forCellIdEx(c2, i, c) {
|
||||||
placeSidewallX(c, i, SIDE_SLEV, V, warp, false, darkena(wcol2, fd, 0xFF));
|
placeSidewallX(c, i, SIDE_SLEV, V, warp, false, darkena(wcol2, fd, alpha));
|
||||||
}
|
}
|
||||||
forCellIdEx(c2, i, c) {
|
forCellIdEx(c2, i, c) {
|
||||||
placeSidewallX(c, i, SIDE_SLEV+1, V, warp, false, darkena(wcol2, fd, 0xFF));
|
placeSidewallX(c, i, SIDE_SLEV+1, V, warp, false, darkena(wcol2, fd, alpha));
|
||||||
}
|
}
|
||||||
forCellIdEx(c2, i, c) {
|
forCellIdEx(c2, i, c) {
|
||||||
placeSidewallX(c, i, SIDE_SLEV+2, V, warp, false, darkena(wcol2, fd, 0xFF));
|
placeSidewallX(c, i, SIDE_SLEV+2, V, warp, false, darkena(wcol2, fd, alpha));
|
||||||
}
|
}
|
||||||
forCellIdEx(c2, i, c) {
|
forCellIdEx(c2, i, c) {
|
||||||
placeSidewallX(c, i, SIDE_WTS3, V, warp, false, darkena(wcol2, fd, 0xFF));
|
placeSidewallX(c, i, SIDE_WTS3, V, warp, false, darkena(wcol2, fd, alpha));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else forCellIdEx(c2, i, c) {
|
else forCellIdEx(c2, i, c) {
|
||||||
if(!highwall(c2) || conegraph(c2))
|
if(!highwall(c2) || conegraph(c2))
|
||||||
{ placeSidewallX(c, i, SIDE_WALL, V, warp, false, darkena(wcol2, fd, 0xFF)); }
|
{ placeSidewallX(c, i, SIDE_WALL, V, warp, false, darkena(wcol2, fd, alpha)); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3872,6 +3959,11 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
queuepoly(V * spin(M_PI/6 - fanframe * M_PI / 3), shFan, darkena(wcol, 0, 0xFF));
|
queuepoly(V * spin(M_PI/6 - fanframe * M_PI / 3), shFan, darkena(wcol, 0, 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(c->wall == waArrowTrap) {
|
||||||
|
int trapcol[4] = {0x904040, 0xA02020, 0xD00000, 0x303030};
|
||||||
|
queuepoly(V, shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
else if(xch == '%') {
|
else if(xch == '%') {
|
||||||
if(doHighlight())
|
if(doHighlight())
|
||||||
poly_outline = (c->land == laMirror) ? OUTLINE_TREASURE : OUTLINE_ORB;
|
poly_outline = (c->land == laMirror) ? OUTLINE_TREASURE : OUTLINE_ORB;
|
||||||
@ -3912,6 +4004,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
else if(xch != '.' && xch != '+' && xch != '>' && xch != ':'&& xch != '-' && xch != ';' && c->wall != waSulphur && xch != ',')
|
else if(xch != '.' && xch != '+' && xch != '>' && xch != ':'&& xch != '-' && xch != ';' && c->wall != waSulphur && xch != ',')
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(!(it || c->monst || c->cpdist == 0)) error = true;
|
else if(!(it || c->monst || c->cpdist == 0)) error = true;
|
||||||
|
|
||||||
int sha = shallow(c);
|
int sha = shallow(c);
|
||||||
@ -4070,6 +4163,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c->land == laBlizzard)
|
||||||
|
blizzardcells[c].frame = frameid;
|
||||||
|
|
||||||
if(c->land == laWhirlwind) {
|
if(c->land == laWhirlwind) {
|
||||||
whirlwind::calcdirs(c);
|
whirlwind::calcdirs(c);
|
||||||
|
|
||||||
@ -4472,6 +4568,7 @@ void drawFlashes() {
|
|||||||
|
|
||||||
bool allowIncreasedSight() {
|
bool allowIncreasedSight() {
|
||||||
if(cheater) return true;
|
if(cheater) return true;
|
||||||
|
if(inHighQual) return true;
|
||||||
if(peace::on) return true;
|
if(peace::on) return true;
|
||||||
#if CAP_TOUR
|
#if CAP_TOUR
|
||||||
if(tour::on) return true;
|
if(tour::on) return true;
|
||||||
@ -4487,7 +4584,7 @@ void drawthemap() {
|
|||||||
|
|
||||||
frameid++;
|
frameid++;
|
||||||
|
|
||||||
wavephase = (-(SDL_GetTicks() / 100)) & 7;
|
wavephase = (-(ticks / 100)) & 7;
|
||||||
|
|
||||||
if(!allowIncreasedSight()) {
|
if(!allowIncreasedSight()) {
|
||||||
if(sightrange > 7) sightrange = 7;
|
if(sightrange > 7) sightrange = 7;
|
||||||
@ -4562,6 +4659,7 @@ void drawthemap() {
|
|||||||
maxreclevel,
|
maxreclevel,
|
||||||
hsOrigin, ypush(vid.yshift) * sphereflip * View);
|
hsOrigin, ypush(vid.yshift) * sphereflip * View);
|
||||||
}
|
}
|
||||||
|
drawBlizzards();
|
||||||
ivoryz = false;
|
ivoryz = false;
|
||||||
|
|
||||||
linepatterns::drawAll();
|
linepatterns::drawAll();
|
||||||
|
10
hyper.cpp
10
hyper.cpp
@ -150,6 +150,12 @@ int arg::readCommon() {
|
|||||||
shift(); int q = argi();
|
shift(); int q = argi();
|
||||||
placeItems(q, i);
|
placeItems(q, i);
|
||||||
}
|
}
|
||||||
|
else if(argis("-ambush")) {
|
||||||
|
// make all ambushes use the given number of dogs
|
||||||
|
// example: hyper -W Hunt -IP Shield 1 -ambush 60
|
||||||
|
PHASE(3) cheater++; timerghost = false;
|
||||||
|
shift(); ambushval = argi();
|
||||||
|
}
|
||||||
else if(argis("-M")) {
|
else if(argis("-M")) {
|
||||||
PHASE(3) cheater++; timerghost = false;
|
PHASE(3) cheater++; timerghost = false;
|
||||||
shift(); eMonster m = readMonster(args());
|
shift(); eMonster m = readMonster(args());
|
||||||
@ -272,6 +278,10 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
|
|||||||
fieldpattern::info();
|
fieldpattern::info();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
else if(argis("-quantum")) {
|
||||||
|
quantum = true;
|
||||||
|
autocheat = true;
|
||||||
|
}
|
||||||
else if(argis("-P")) {
|
else if(argis("-P")) {
|
||||||
PHASE(2); shift();
|
PHASE(2); shift();
|
||||||
vid.scfg.players = argi();
|
vid.scfg.players = argi();
|
||||||
|
141
hyper.h
141
hyper.h
@ -53,7 +53,8 @@ void achievement_pump();
|
|||||||
vector<string> achievementsReceived;
|
vector<string> achievementsReceived;
|
||||||
|
|
||||||
// game forward declarations
|
// game forward declarations
|
||||||
typedef int flagtype;
|
typedef unsigned long long flagtype;
|
||||||
|
#define Flag(i) (flagtype(1ull<<i))
|
||||||
|
|
||||||
bool mirrorkill(cell *c);
|
bool mirrorkill(cell *c);
|
||||||
bool isNeighbor(cell *c1, cell *c2);
|
bool isNeighbor(cell *c1, cell *c2);
|
||||||
@ -461,38 +462,39 @@ void setGLProjection();
|
|||||||
|
|
||||||
// passable flags
|
// passable flags
|
||||||
|
|
||||||
#define P_MONSTER (1<<0) // can move through monsters
|
#define P_MONSTER Flag(0) // can move through monsters
|
||||||
#define P_MIRROR (1<<1) // can move through mirrors
|
#define P_MIRROR Flag(1) // can move through mirrors
|
||||||
#define P_REVDIR (1<<2) // reverse direction movement
|
#define P_REVDIR Flag(2) // reverse direction movement
|
||||||
#define P_WIND (1<<3) // can move against the wind
|
#define P_WIND Flag(3) // can move against the wind
|
||||||
#define P_GRAVITY (1<<4) // can move against the gravity
|
#define P_GRAVITY Flag(4) // can move against the gravity
|
||||||
#define P_ISPLAYER (1<<5) // player-only moves (like the Round Table jump)
|
#define P_ISPLAYER Flag(5) // player-only moves (like the Round Table jump)
|
||||||
#define P_ONPLAYER (1<<6) // always can step on the player
|
#define P_ONPLAYER Flag(6) // always can step on the player
|
||||||
#define P_FLYING (1<<7) // is flying
|
#define P_FLYING Flag(7) // is flying
|
||||||
#define P_BULLET (1<<8) // bullet can fly through more things
|
#define P_BULLET Flag(8) // bullet can fly through more things
|
||||||
#define P_MIRRORWALL (1<<9) // mirror images go through mirror walls
|
#define P_MIRRORWALL Flag(9) // mirror images go through mirror walls
|
||||||
#define P_JUMP1 (1<<10) // first part of a jump
|
#define P_JUMP1 Flag(10) // first part of a jump
|
||||||
#define P_JUMP2 (1<<11) // second part of a jump
|
#define P_JUMP2 Flag(11) // second part of a jump
|
||||||
#define P_TELE (1<<12) // teleport onto
|
#define P_TELE Flag(12) // teleport onto
|
||||||
#define P_BLOW (1<<13) // Orb of Air -- blow, or push
|
#define P_BLOW Flag(13) // Orb of Air -- blow, or push
|
||||||
#define P_AETHER (1<<14) // aethereal
|
#define P_AETHER Flag(14) // aethereal
|
||||||
#define P_FISH (1<<15) // swimming
|
#define P_FISH Flag(15) // swimming
|
||||||
#define P_WINTER (1<<16) // fire resistant
|
#define P_WINTER Flag(16) // fire resistant
|
||||||
#define P_USEBOAT (1<<17) // can use boat
|
#define P_USEBOAT Flag(17) // can use boat
|
||||||
#define P_NOAETHER (1<<18) // disable AETHER
|
#define P_NOAETHER Flag(18) // disable AETHER
|
||||||
#define P_FRIENDSWAP (1<<19) // can move on friends (to swap with tem)
|
#define P_FRIENDSWAP Flag(19) // can move on friends (to swap with tem)
|
||||||
#define P_ISFRIEND (1<<20) // is a friend (can use Empathy + Winter/Aether/Fish combo)
|
#define P_ISFRIEND Flag(20) // is a friend (can use Empathy + Winter/Aether/Fish combo)
|
||||||
#define P_LEADER (1<<21) // can push statues and use boats
|
#define P_LEADER Flag(21) // can push statues and use boats
|
||||||
#define P_MARKWATER (1<<22) // mark Orb of Water as used
|
#define P_MARKWATER Flag(22) // mark Orb of Water as used
|
||||||
#define P_EARTHELEM (1<<23) // Earth Elemental
|
#define P_EARTHELEM Flag(23) // Earth Elemental
|
||||||
#define P_WATERELEM (1<<24) // Water Elemental
|
#define P_WATERELEM Flag(24) // Water Elemental
|
||||||
#define P_IGNORE37 (1<<25) // ignore the triheptagonal board
|
#define P_IGNORE37 Flag(25) // ignore the triheptagonal board
|
||||||
#define P_CHAIN (1<<26) // for chaining moves with boats
|
#define P_CHAIN Flag(26) // for chaining moves with boats
|
||||||
#define P_DEADLY (1<<27) // suicide moves allowed
|
#define P_DEADLY Flag(27) // suicide moves allowed
|
||||||
#define P_ROSE (1<<28) // rose smell
|
#define P_ROSE Flag(28) // rose smell
|
||||||
#define P_CLIMBUP (1<<29) // allow climbing up
|
#define P_CLIMBUP Flag(29) // allow climbing up
|
||||||
#define P_CLIMBDOWN (1<<30) // allow climbing down
|
#define P_CLIMBDOWN Flag(30) // allow climbing down
|
||||||
#define P_REPTILE (1<<31) // is reptile
|
#define P_REPTILE Flag(31) // is reptile
|
||||||
|
#define P_VOID Flag(32) // void beast
|
||||||
|
|
||||||
bool passable(cell *w, cell *from, flagtype flags);
|
bool passable(cell *w, cell *from, flagtype flags);
|
||||||
|
|
||||||
@ -646,38 +648,39 @@ bool withRose(cell *cfrom, cell *cto);
|
|||||||
|
|
||||||
// canAttack/moveval flags
|
// canAttack/moveval flags
|
||||||
|
|
||||||
#define AF_TOUGH (1<<0) // tough attacks: Hyperbugs
|
#define AF_TOUGH Flag(0) // tough attacks: Hyperbugs
|
||||||
#define AF_MAGIC (1<<1) // magical attacks: Flash
|
#define AF_MAGIC Flag(1) // magical attacks: Flash
|
||||||
#define AF_STAB (1<<2) // stabbing attacks (usually ignored except Hedgehogs)
|
#define AF_STAB Flag(2) // stabbing attacks (usually ignored except Hedgehogs)
|
||||||
#define AF_LANCE (1<<3) // lance attacks (used by Lancers)
|
#define AF_LANCE Flag(3) // lance attacks (used by Lancers)
|
||||||
#define AF_ONLY_ENEMY (1<<4) // only say YES if it is an enemy
|
#define AF_ONLY_ENEMY Flag(4) // only say YES if it is an enemy
|
||||||
#define AF_ONLY_FRIEND (1<<5) // only say YES if it is a friend
|
#define AF_ONLY_FRIEND Flag(5) // only say YES if it is a friend
|
||||||
#define AF_ONLY_FBUG (1<<6) // only say YES if it is a bug_or friend
|
#define AF_ONLY_FBUG Flag(6) // only say YES if it is a bug_or friend
|
||||||
#define AF_BACK (1<<7) // backward attacks (ignored except Viziers and Flailers)
|
#define AF_BACK Flag(7) // backward attacks (ignored except Viziers and Flailers)
|
||||||
#define AF_APPROACH (1<<8) // approach attacks (ignored except Lancers)
|
#define AF_APPROACH Flag(8) // approach attacks (ignored except Lancers)
|
||||||
#define AF_IGNORE_UNARMED (1<<9) // ignore the UNARMED flag
|
#define AF_IGNORE_UNARMED Flag(9) // ignore the UNARMED flag
|
||||||
#define AF_NOSHIELD (1<<10) // ignore the shielded status
|
#define AF_NOSHIELD Flag(10) // ignore the shielded status
|
||||||
#define AF_GETPLAYER (1<<11) // check for player (replace m2 with moPlayer for player position)
|
#define AF_GETPLAYER Flag(11) // check for player (replace m2 with moPlayer for player position)
|
||||||
#define AF_GUN (1<<12) // revolver attack
|
#define AF_GUN Flag(12) // revolver attack
|
||||||
#define AF_FAST (1<<13) // fast attack
|
#define AF_FAST Flag(13) // fast attack
|
||||||
#define AF_EAT (1<<17) // eating attacks from Worm-likes
|
#define AF_EAT Flag(17) // eating attacks from Worm-likes
|
||||||
|
|
||||||
#define MF_NOATTACKS (1<<14) // don't do any attacks
|
#define MF_NOATTACKS Flag(14) // don't do any attacks
|
||||||
#define MF_PATHDIST (1<<15) // consider pathdist for moveval
|
#define MF_PATHDIST Flag(15) // consider pathdist for moveval
|
||||||
#define MF_ONLYEAGLE (1<<16) // do this only for Eagles
|
#define MF_ONLYEAGLE Flag(16) // do this only for Eagles
|
||||||
#define MF_MOUNT (1<<18) // don't do
|
#define MF_MOUNT Flag(18) // don't do
|
||||||
#define MF_NOFRIEND (1<<19) // don't do it for friends
|
#define MF_NOFRIEND Flag(19) // don't do it for friends
|
||||||
|
|
||||||
#define AF_SWORD (1<<20) // big sword
|
#define AF_SWORD Flag(20) // big sword
|
||||||
#define AF_SWORD_INTO (1<<21) // moving into big sword
|
#define AF_SWORD_INTO Flag(21) // moving into big sword
|
||||||
#define AF_MSG (1<<22) // produce a message
|
#define AF_MSG Flag(22) // produce a message
|
||||||
#define AF_ORSTUN (1<<23) // attackMonster: allow stunning
|
#define AF_ORSTUN Flag(23) // attackMonster: allow stunning
|
||||||
#define AF_NEXTTURN (1<<24) // next turn -- don't count shield at power 1
|
#define AF_NEXTTURN Flag(24) // next turn -- don't count shield at power 1
|
||||||
#define AF_FALL (1<<25) // death by falling
|
#define AF_FALL Flag(25) // death by falling
|
||||||
#define MF_STUNNED (1<<26) // edgeunstable: ignore ladders (as stunned monsters do)
|
#define MF_STUNNED Flag(26) // edgeunstable: ignore ladders (as stunned monsters do)
|
||||||
#define MF_IVY (1<<27) // edgeunstable: ignore ivy (ivy cannot climb ivy)
|
#define MF_IVY Flag(27) // edgeunstable: ignore ivy (ivy cannot climb ivy)
|
||||||
#define AF_HORNS (1<<28) // spear attack (always has APPROACH too)
|
#define AF_HORNS Flag(28) // spear attack (always has APPROACH too)
|
||||||
#define AF_BULL (1<<29) // bull attack
|
#define AF_BULL Flag(29) // bull attack
|
||||||
|
#define AF_SIDE Flag(30) // side attack
|
||||||
|
|
||||||
bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags);
|
bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags);
|
||||||
|
|
||||||
@ -857,7 +860,7 @@ void resetGeometry();
|
|||||||
|
|
||||||
namespace svg {
|
namespace svg {
|
||||||
void circle(int x, int y, int size, int col);
|
void circle(int x, int y, int size, int col);
|
||||||
void polygon(int *polyx, int *polyy, int polyi, int col, int outline);
|
void polygon(int *polyx, int *polyy, int polyi, int col, int outline, double minwidth);
|
||||||
void text(int x, int y, int size, const string& str, bool frame, int col, int align);
|
void text(int x, int y, int size, const string& str, bool frame, int col, int align);
|
||||||
extern bool in;
|
extern bool in;
|
||||||
extern string *info;
|
extern string *info;
|
||||||
@ -1533,6 +1536,16 @@ static bool orbProtection(eItem it) { return false; } // not implemented
|
|||||||
|
|
||||||
namespace windmap {
|
namespace windmap {
|
||||||
void create();
|
void create();
|
||||||
|
|
||||||
|
static const int NOWINDBELOW = 8;
|
||||||
|
static const int NOWINDFROM = 120;
|
||||||
|
|
||||||
|
int at(cell *c);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int wavephase;
|
extern int wavephase;
|
||||||
|
|
||||||
|
void buildEquidistant(cell *c);
|
||||||
|
void produceGhost(cell *c, eMonster victim, eMonster who);
|
||||||
|
void sideAttack(cell *mf, int dir, eMonster who, int bonus, eItem orb);
|
||||||
|
void sideAttack(cell *mf, int dir, eMonster who, int bonuskill);
|
||||||
|
134
landgen.cpp
134
landgen.cpp
@ -221,7 +221,16 @@ int isNative(eLand l, eMonster m) {
|
|||||||
return (m == moRagingBull || m == moHerdBull || m == moGadfly) ? 1 : 0;
|
return (m == moRagingBull || m == moHerdBull || m == moGadfly) ? 1 : 0;
|
||||||
|
|
||||||
case laAlchemy2:
|
case laAlchemy2:
|
||||||
return false;
|
return m == moLemur ? 2 : 0;
|
||||||
|
|
||||||
|
case laTerracotta:
|
||||||
|
return m == moMercuryGuy ? 2 : m == moTerraWarrior ? 1 : 0;
|
||||||
|
|
||||||
|
case laBlizzard:
|
||||||
|
return (m == moVoidBeast || m == moIceGolem) ? 2 : 0;
|
||||||
|
|
||||||
|
case laDogPlains:
|
||||||
|
return m == moHunterDog ? 1 : 0;
|
||||||
|
|
||||||
case laCA: return false;
|
case laCA: return false;
|
||||||
}
|
}
|
||||||
@ -311,7 +320,11 @@ eItem treasureType(eLand l) {
|
|||||||
case laBull: return itBull;
|
case laBull: return itBull;
|
||||||
case laPrairie: return itGreenGrass;
|
case laPrairie: return itGreenGrass;
|
||||||
|
|
||||||
case laAlchemy2: return itElixir;
|
case laAlchemy2: return itAlchemy2;
|
||||||
|
case laTerracotta: return itTerra;
|
||||||
|
case laBlizzard: return itBlizzard;
|
||||||
|
case laDogPlains: return itDogPlains;
|
||||||
|
|
||||||
case laCA: return itNone;
|
case laCA: return itNone;
|
||||||
}
|
}
|
||||||
return itNone;
|
return itNone;
|
||||||
@ -767,6 +780,15 @@ bool landUnlocked(eLand l) {
|
|||||||
case laAlchemy2:
|
case laAlchemy2:
|
||||||
return gold() >= R30 && items[itElixir] >= U10;
|
return gold() >= R30 && items[itElixir] >= U10;
|
||||||
|
|
||||||
|
case laDogPlains:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case laTerracotta:
|
||||||
|
return gold() >= 60;
|
||||||
|
|
||||||
|
case laBlizzard:
|
||||||
|
return items[itDiamond] >= 5 && items[itWindstone] >= 5;
|
||||||
|
|
||||||
case laCrossroads5:
|
case laCrossroads5:
|
||||||
return gold() >= R300;
|
return gold() >= R300;
|
||||||
}
|
}
|
||||||
@ -3512,6 +3534,15 @@ int reptilemax() {
|
|||||||
|
|
||||||
bool is02(int i) { return i == 0 || i == 2; }
|
bool is02(int i) { return i == 0 || i == 2; }
|
||||||
|
|
||||||
|
bool openplains(cell *c) {
|
||||||
|
celllister cl(c, purehepta ? 5 : 7, 1000000, NULL);
|
||||||
|
for(cell *c: cl.lst) {
|
||||||
|
while(c->mpdist > 8) setdist(c, c->mpdist-1, NULL);
|
||||||
|
if(c->land != laDogPlains) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// This function generates all lands. Warning: it's very long!
|
// This function generates all lands. Warning: it's very long!
|
||||||
void setdist(cell *c, int d, cell *from) {
|
void setdist(cell *c, int d, cell *from) {
|
||||||
|
|
||||||
@ -3611,7 +3642,7 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
else buildPrizeMirror(c, 1000);
|
else buildPrizeMirror(c, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(d == 7)
|
if(d == 7)
|
||||||
prairie::generateTreasure(c);
|
prairie::generateTreasure(c);
|
||||||
|
|
||||||
@ -3986,7 +4017,55 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
|
|
||||||
if(c->land == laAlchemist)
|
if(c->land == laAlchemist)
|
||||||
c->wall = (randomPatternsMode ? RANDPAT : hrand(2)) ? waFloorA : waFloorB;
|
c->wall = (randomPatternsMode ? RANDPAT : hrand(2)) ? waFloorA : waFloorB;
|
||||||
|
|
||||||
|
if(c->land == laAlchemy2)
|
||||||
|
c->wall = waSlime1;
|
||||||
|
|
||||||
|
if(c->land == laBlizzard) {
|
||||||
|
bool windless = true;
|
||||||
|
int w = windmap::at(c);
|
||||||
|
forCellCM(c2, c) {
|
||||||
|
int w2 = windmap::at(c2);
|
||||||
|
if(((w2-w) & 255) >= windmap::NOWINDBELOW)
|
||||||
|
if(((w-w2) & 255) >= windmap::NOWINDBELOW)
|
||||||
|
windless = false;
|
||||||
|
}
|
||||||
|
if(windless) {
|
||||||
|
c->wall = waIcewall;
|
||||||
|
if(hrand(500) < PT(100 + 2 * kills[moVoidBeast] + 2 * kills[moIceGolem], 200) && notDippingFor(itBlizzard))
|
||||||
|
c->item = itBlizzard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->land == laTerracotta) {
|
||||||
|
if(hrand(500) < 15) {
|
||||||
|
cellwalker cw(c, hrand(c->type));
|
||||||
|
cell* cc[5];
|
||||||
|
cc[2] = c;
|
||||||
|
cellwalker cw2 = cw;
|
||||||
|
cwstep(cw); cc[3] = cw.c; cwrevstep(cw); cc[4] = cw.c;
|
||||||
|
cwrevstep(cw2); cc[1] = cw2.c; cwrevstep(cw2); cc[0] = cw2.c;
|
||||||
|
bool ok = true;
|
||||||
|
for(int i=1; i<4; i++) {
|
||||||
|
forCellEx(c2, cc[i]) if(c2->wall == waArrowTrap) ok = false;
|
||||||
|
if(cc[i]->land != laNone && cc[i]->land != laTerracotta) ok = false;
|
||||||
|
if(cc[i]->bardir != NODIR) ok = false;
|
||||||
|
cc[i]->bardir = NOBARRIERS;
|
||||||
|
}
|
||||||
|
if(ok) {
|
||||||
|
for(int i=1; i<4; i++)
|
||||||
|
cc[i]->wall = waArrowTrap,
|
||||||
|
cc[i]->wparam = 0;
|
||||||
|
cc[0]->wall = waStone;
|
||||||
|
cc[4]->wall = waStone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pseudohept(c) && hrand(100) < 40 && c->wall == waNone) {
|
||||||
|
c->wall = waTerraWarrior;
|
||||||
|
c->landparam = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(c->land == laDryForest) {
|
if(c->land == laDryForest) {
|
||||||
if(randomPatternsMode)
|
if(randomPatternsMode)
|
||||||
c->wall = RANDPAT ? waNone : RANDPATV(laHell) ? waBigTree : waSmallTree;
|
c->wall = RANDPAT ? waNone : RANDPATV(laHell) ? waBigTree : waSmallTree;
|
||||||
@ -4652,6 +4731,23 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
|
|
||||||
if(d == 7 && c->land == laCaves && c->wall == waCavewall && hrand(5000) < items[itGold] + hard && !safety)
|
if(d == 7 && c->land == laCaves && c->wall == waCavewall && hrand(5000) < items[itGold] + hard && !safety)
|
||||||
c->monst = moSeep;
|
c->monst = moSeep;
|
||||||
|
|
||||||
|
if(d == 7 && c->land == laDogPlains) {
|
||||||
|
if(hrand(1000) < 10) {
|
||||||
|
if(openplains(c)) {
|
||||||
|
c->item = itDogPlains;
|
||||||
|
vector<cell*> next;
|
||||||
|
forCellEx(c2, c) if(c2->mpdist > 7) next.push_back(c2);
|
||||||
|
if(size(next) && items[itDogPlains] < 10) {
|
||||||
|
cell *c3 = next[hrand(size(next))];
|
||||||
|
forCellEx(c4, c3) if(c4->mpdist > 7 && !isNeighbor(c4, c))
|
||||||
|
c4->monst = moHunterGuard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hrand(5000) < items[itDogPlains]- 17 + hard)
|
||||||
|
c->monst = moHunterDog;
|
||||||
|
}
|
||||||
|
|
||||||
if(d == 7 && c->land == laLivefjord && c->wall == waSea && hrand(5000) < 15 + items[itFjord] + hard && !safety) {
|
if(d == 7 && c->land == laLivefjord && c->wall == waSea && hrand(5000) < 15 + items[itFjord] + hard && !safety) {
|
||||||
if(items[itFjord] >= 5 && hrand(100) < 20 && !peace::on)
|
if(items[itFjord] >= 5 && hrand(100) < 20 && !peace::on)
|
||||||
@ -4821,7 +4917,7 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
placePrizeOrb(c);
|
placePrizeOrb(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(d == 7 && c->wall == waIcewall && c->land != laIce && c->land != laCocytus)
|
if(d == 7 && c->wall == waIcewall && c->land != laIce && c->land != laCocytus && c->land != laBlizzard)
|
||||||
c->wall = waNone;
|
c->wall = waNone;
|
||||||
|
|
||||||
if(d == 7 && c->wall == waRed3 && c->land != laRedRock)
|
if(d == 7 && c->wall == waRed3 && c->land != laRedRock)
|
||||||
@ -4972,6 +5068,27 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
if(hrand(8000) < 2 * (items[itDiamond] + hard))
|
if(hrand(8000) < 2 * (items[itDiamond] + hard))
|
||||||
c->monst = hrand(2) ? moYeti : moWolf;
|
c->monst = hrand(2) ? moYeti : moWolf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c->land == laBlizzard) {
|
||||||
|
if(hrand(8000) < 10 + 2 * (items[itBlizzard] + hard))
|
||||||
|
c->monst = pick(moVoidBeast, moIceGolem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->land == laAlchemy2) {
|
||||||
|
if(hrand(5000) < PT(100 + 2 * kills[moLemur], 200) && notDippingFor(itAlchemy2))
|
||||||
|
c->item = itAlchemy2;
|
||||||
|
if(hrand(8000) < 2 * (items[itAlchemy2] + hard))
|
||||||
|
c->monst = moLemur;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->land == laTerracotta) {
|
||||||
|
bool nearwarrior = false;
|
||||||
|
forCellEx(c2, c) if(c2->wall == waTerraWarrior) nearwarrior = true;
|
||||||
|
if(nearwarrior && hrand(5000) < PT(100 + 2 * kills[moMercuryGuy], 200) && notDippingFor(itTerra))
|
||||||
|
c->item = itTerra;
|
||||||
|
if(hrand(8000) < 2 * (items[itTerra] + hard))
|
||||||
|
c->monst = moMercuryGuy;
|
||||||
|
}
|
||||||
|
|
||||||
if(c->land == laTrollheim && !safety) {
|
if(c->land == laTrollheim && !safety) {
|
||||||
if(hrand(8000) < items[itTrollEgg] + hardness_empty())
|
if(hrand(8000) < items[itTrollEgg] + hardness_empty())
|
||||||
@ -5482,7 +5599,7 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wchance(int a, int of) {
|
bool wchance(int a, int of, int reduction = 0) {
|
||||||
of *= 10;
|
of *= 10;
|
||||||
a += yendor::hardness() + 1;
|
a += yendor::hardness() + 1;
|
||||||
if(isCrossroads(cwt.c->land))
|
if(isCrossroads(cwt.c->land))
|
||||||
@ -5492,6 +5609,10 @@ bool wchance(int a, int of) {
|
|||||||
|
|
||||||
for(int i=0; i<ittypes; i++) if(itemclass(eItem(i)) == IC_TREASURE)
|
for(int i=0; i<ittypes; i++) if(itemclass(eItem(i)) == IC_TREASURE)
|
||||||
a = max(a, (items[i]-R10) / 10);
|
a = max(a, (items[i]-R10) / 10);
|
||||||
|
|
||||||
|
a -= reduction;
|
||||||
|
if(a < 0) return false;
|
||||||
|
|
||||||
return hrand(a+of) < a;
|
return hrand(a+of) < a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5721,6 +5842,9 @@ void wandering() {
|
|||||||
else if(c->land == laIce && wchance(items[itDiamond], 10))
|
else if(c->land == laIce && wchance(items[itDiamond], 10))
|
||||||
c->monst = hrand(2) ? moWolf : moYeti;
|
c->monst = hrand(2) ? moWolf : moYeti;
|
||||||
|
|
||||||
|
else if(c->land == laDogPlains && wchance(items[itDogPlains], 50, 26))
|
||||||
|
c->monst = moHunterDog;
|
||||||
|
|
||||||
else if(c->land == laDesert && wchance(items[itSpice], 10))
|
else if(c->land == laDesert && wchance(items[itSpice], 10))
|
||||||
c->monst = (hrand(10) || peace::on) ? moDesertman : moWorm;
|
c->monst = (hrand(10) || peace::on) ? moDesertman : moWorm;
|
||||||
|
|
||||||
|
6
orbs.cpp
6
orbs.cpp
@ -440,8 +440,7 @@ void castLightningBolt(cellwalker lig) {
|
|||||||
bnc++; if(bnc > 10) break;
|
bnc++; if(bnc > 10) break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cwspin(lig, 3);
|
cwrev(lig);
|
||||||
if(c->type == 7) cwspin(lig, hrand(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lig.c->wall == waCloud) {
|
if(lig.c->wall == waCloud) {
|
||||||
@ -654,8 +653,6 @@ eMonster summonedAt(cell *dest) {
|
|||||||
return dest->land == laPalace ? moPalace : moBat;
|
return dest->land == laPalace ? moPalace : moBat;
|
||||||
if(dest->wall == waFloorA || dest->wall == waFloorB)
|
if(dest->wall == waFloorA || dest->wall == waFloorB)
|
||||||
return moSlime;
|
return moSlime;
|
||||||
if(dest->wall == waFloorC || dest->wall == waFloorD)
|
|
||||||
return moRatling;
|
|
||||||
if(dest->wall == waCavefloor)
|
if(dest->wall == waCavefloor)
|
||||||
return moTroll;
|
return moTroll;
|
||||||
if(dest->wall == waDeadfloor)
|
if(dest->wall == waDeadfloor)
|
||||||
@ -698,6 +695,7 @@ eMonster summonedAt(cell *dest) {
|
|||||||
if(dest->wall == waGiantRug)
|
if(dest->wall == waGiantRug)
|
||||||
return moVizier;
|
return moVizier;
|
||||||
if(dest->wall == waNone) {
|
if(dest->wall == waNone) {
|
||||||
|
if(dest->land == laDogPlains) return moAirElemental;
|
||||||
if(dest->land == laBull) return moRagingBull;
|
if(dest->land == laBull) return moRagingBull;
|
||||||
if(dest->land == laPrairie) return moAirElemental;
|
if(dest->land == laPrairie) return moAirElemental;
|
||||||
if(dest->land == laZebra) return moAirElemental;
|
if(dest->land == laZebra) return moAirElemental;
|
||||||
|
Loading…
Reference in New Issue
Block a user