mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 01:00:25 +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 "
|
||||
"missiles perfectly.";
|
||||
|
||||
const int motypes = 141;
|
||||
const int motypes = 150;
|
||||
|
||||
struct monstertype {
|
||||
char glyph;
|
||||
@ -696,6 +696,14 @@ monstertype minf[motypes] = {
|
||||
"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."
|
||||
},
|
||||
{ '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
|
||||
{ '@', 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."},
|
||||
// technical
|
||||
{ '?', 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, "Energy Sword", NODESC},
|
||||
{ '!', 0xFF0000, "Warning", warningdesc},
|
||||
{ '!', 0xFF0000, "arrow trap", NODESC},
|
||||
{ '*', 0, "vertex", "A vertex from rogueviz."}
|
||||
};
|
||||
|
||||
@ -756,10 +765,12 @@ enum eMonster {
|
||||
moVampire, moBat, moReptile,
|
||||
moHerdBull, moRagingBull, moSleepBull,
|
||||
moButterfly, moNarciss, moMirrorSpirit,
|
||||
moHunterDog, moTerraWarrior, moMercuryGuy, moVoidBeast, moLemur, moHunterGuard,
|
||||
moIceGolem, moSandBird,
|
||||
// shmup specials
|
||||
moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball,
|
||||
// temporary
|
||||
moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning,
|
||||
moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning, moArrowTrap,
|
||||
moRogueviz
|
||||
};
|
||||
|
||||
@ -790,7 +801,7 @@ genderswitch_t genderswitch[NUM_GS] = {
|
||||
|
||||
// --- items ---
|
||||
|
||||
const int ittypes = 112;
|
||||
const int ittypes = 119;
|
||||
|
||||
struct itemtype {
|
||||
char glyph;
|
||||
@ -1183,6 +1194,13 @@ itemtype iinf[ittypes] = {
|
||||
},
|
||||
{ 'O', 0xF0F0F0, "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,
|
||||
@ -1216,12 +1234,14 @@ enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBo
|
||||
itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat,
|
||||
itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns,
|
||||
itOrbBull, itBull, itOrbMirror,
|
||||
itInventory
|
||||
itInventory,
|
||||
itAlchemy2, itDogPlains, itBlizzard, itTerra,
|
||||
itOrbSide1, itOrbSide2, itOrbSide3
|
||||
};
|
||||
|
||||
// --- wall types ---
|
||||
|
||||
const int walltypes = 100;
|
||||
const int walltypes = 103;
|
||||
|
||||
struct walltype {
|
||||
char glyph;
|
||||
@ -1372,8 +1392,8 @@ walltype winf[walltypes] = {
|
||||
{ '?', 0xFF00FF, "<earth d", NODESC},
|
||||
{ '?', 0xFF00FF, "<elemental tmp>", NODESC},
|
||||
{ '?', 0xFF00FF, "<elemental d>", NODESC},
|
||||
{ '+', 0x607030, "unnamed floor C", NODESC},
|
||||
{ '+', 0xC0C0FF, "unnamed floor D", NODESC},
|
||||
{ '+', 0x00F000, "green slime", NODESC},
|
||||
{ '+', 0xF0F000, "yellow slime", NODESC},
|
||||
{ '#', 0x764e7c, "rosebush", roselanddesc},
|
||||
{ '#', 0xC0C000, "warp gate",
|
||||
"This gate separates the warped area from the normal land."},
|
||||
@ -1404,6 +1424,9 @@ walltype winf[walltypes] = {
|
||||
{ '#', 0xC0C0FF, "mirror wall", mirroreddesc},
|
||||
{ '.', 0xE0E0E0, "stepping stones", "A petrified creature."},
|
||||
{ '#', 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,
|
||||
@ -1426,7 +1449,7 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
|
||||
waCharged, waGrounded, waSandstone, waSaloon, waMetal,
|
||||
waDeadTroll2, waFan,
|
||||
waTemporary, waEarthD, waElementalTmp, waElementalD,
|
||||
waFloorC, waFloorD, waRose, waWarpGate,
|
||||
waSlime1, waSlime2, waRose, waWarpGate,
|
||||
waTrunk, waSolidBranch, waWeakBranch, waCanopy,
|
||||
waBarrowWall, waBarrowDig,
|
||||
waPetrified, waTower,
|
||||
@ -1435,12 +1458,14 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
|
||||
waInvisibleFloor,
|
||||
waMirrorWall,
|
||||
waPetrifiedBridge,
|
||||
waTempBridgeBlocked
|
||||
waTempBridgeBlocked,
|
||||
waTerraWarrior, waBubble,
|
||||
waArrowTrap
|
||||
};
|
||||
|
||||
// --- land types ---
|
||||
|
||||
const int landtypes = 73;
|
||||
const int landtypes = 76;
|
||||
|
||||
struct landtype {
|
||||
int color;
|
||||
@ -1623,7 +1648,10 @@ const landtype linf[landtypes] = {
|
||||
{ 0xC8C8FF, "Reflection", mirroreddesc},
|
||||
{ 0xC8C8FF, "Mirror Land",
|
||||
"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,
|
||||
@ -1643,7 +1671,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
|
||||
laPrairie, laBull, laCrossroads5, laCA,
|
||||
laMirrorWall, laMirrored, laMirrorWall2, laMirrored2,
|
||||
laMirrorOld,
|
||||
laAlchemy2
|
||||
laAlchemy2, laBlizzard, laDogPlains, laTerracotta
|
||||
};
|
||||
|
||||
// cell information for the game
|
||||
|
47
complex.cpp
47
complex.cpp
@ -1195,8 +1195,12 @@ namespace mirror {
|
||||
cell *c2 = cw2.c;
|
||||
if(c2->monst) {
|
||||
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);
|
||||
if(!fwd) produceGhost(c2, m2, moMimic);
|
||||
sideAttack(c, m.second.spin, m2, 0);
|
||||
}
|
||||
c->monst = moNone;
|
||||
}
|
||||
if(c2->wall == waBigTree)
|
||||
@ -1758,9 +1762,13 @@ inline float& HEAT(cell *c) { return c->LHU.heat; }
|
||||
|
||||
namespace heat {
|
||||
|
||||
void affect(cell *c, double delta) {
|
||||
if(isIcyLand(c)) HEAT(c) += delta;
|
||||
}
|
||||
|
||||
double absheat(cell *c) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1850,21 +1858,30 @@ namespace heat {
|
||||
forCellEx(ct, c) if(!isIcyLand(ct) && isFire(ct))
|
||||
hmod += xrate*.1;
|
||||
|
||||
for(int j=0; j<c->type; j++) if(c->mov[j]) {
|
||||
if(!isIcyLand(c->mov[j])) {
|
||||
forCellEx(ct, c) {
|
||||
if(!isIcyLand(ct)) {
|
||||
// make sure that we can still enter Cocytus,
|
||||
// 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;
|
||||
continue;
|
||||
}
|
||||
ld hdiff = absheat(c->mov[j]) - absheat(c);
|
||||
ld hdiff = absheat(ct) - absheat(c);
|
||||
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;
|
||||
// if(c->mov[j]->cpdist > 7 && !quotient) hdiff += -HEAT(c) / 30;
|
||||
hmod += hdiff;
|
||||
}
|
||||
// printf("%d ", vsum);
|
||||
|
||||
hmods[i] = hmod;
|
||||
}
|
||||
@ -1971,7 +1988,16 @@ namespace heat {
|
||||
useup(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++) {
|
||||
@ -3044,5 +3070,10 @@ namespace windmap {
|
||||
printf(" return;\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;
|
||||
mirror::act(1, mirror::SPINSINGLE);
|
||||
cwspin(cwt, 1);
|
||||
wavephase = (1+wavephase) & 7;
|
||||
return true;
|
||||
}
|
||||
if(u == 'J') {
|
||||
|
25
flags.cpp
25
flags.cpp
@ -4,7 +4,7 @@
|
||||
// Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details
|
||||
|
||||
bool isIcyLand(eLand l) {
|
||||
return l == laIce || l == laCocytus;
|
||||
return l == laIce || l == laCocytus || l == laBlizzard;
|
||||
}
|
||||
|
||||
bool isIcyLand(cell *c) {
|
||||
@ -24,7 +24,7 @@ bool isWatery(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) {
|
||||
@ -267,7 +267,10 @@ int itemclass(eItem i) {
|
||||
i == itBabyTortoise || i == itDragon || i == itApple ||
|
||||
i == itKraken || i == itBarrow || i == itTrollEgg || i == itTreat ||
|
||||
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;
|
||||
if(i == itSavedPrincess || i == itStrongWind || i == itWarning)
|
||||
return IC_NAI;
|
||||
@ -281,10 +284,18 @@ bool isAlch(eWall w) {
|
||||
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 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); }
|
||||
@ -320,7 +331,8 @@ bool isWall(cell *w) {
|
||||
w->wall == waLadder || w->wall == waTrunk || w->wall == waSolidBranch ||
|
||||
w->wall == waWeakBranch || w->wall == waCanopy || w->wall == waTower ||
|
||||
w->wall == waSmallBush || w->wall == waBigBush ||
|
||||
w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor)
|
||||
w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor ||
|
||||
w->wall == waSlime1 || w->wall == waSlime2 || w->wall == waArrowTrap)
|
||||
return false;
|
||||
if(isWatery(w) || isChasmy(w) || isFire(w)) return false;
|
||||
return true;
|
||||
@ -362,7 +374,8 @@ bool normalMover(eMonster m) {
|
||||
m == moRoseBeauty || m == moWolf ||
|
||||
m == moResearcher || m == moRagingBull ||
|
||||
m == moNarciss || m == moMirrorSpirit ||
|
||||
slowMover(m);
|
||||
m == moHunterDog || m == moTerraWarrior || m == moMercuryGuy || m == moLemur || m == moHunterGuard ||
|
||||
m == moIceGolem || slowMover(m);
|
||||
}
|
||||
|
||||
// from-to
|
||||
|
402
game.cpp
402
game.cpp
@ -23,30 +23,31 @@ int hardcoreAt;
|
||||
|
||||
flagtype havewhat, hadwhat;
|
||||
|
||||
#define HF_BUG (1<<0)
|
||||
#define HF_EARTH (1<<1)
|
||||
#define HF_BIRD (1<<2)
|
||||
#define HF_LEADER (1<<3)
|
||||
#define HF_HEX (1<<4)
|
||||
#define HF_WHIRLPOOL (1<<5)
|
||||
#define HF_WATER (1<<6)
|
||||
#define HF_AIR (1<<7)
|
||||
#define HF_MUTANT (1<<8)
|
||||
#define HF_OUTLAW (1<<9)
|
||||
#define HF_WHIRLWIND (1<<10)
|
||||
#define HF_ROSE (1<<11)
|
||||
#define HF_DRAGON (1<<12)
|
||||
#define HF_KRAKEN (1<<13)
|
||||
#define HF_SHARK (1<<14)
|
||||
#define HF_BATS (1<<15)
|
||||
#define HF_REPTILE (1<<16)
|
||||
#define HF_EAGLES (1<<17)
|
||||
#define HF_SLOW (1<<18)
|
||||
#define HF_FAST (1<<19)
|
||||
#define HF_WARP (1<<20)
|
||||
#define HF_MOUSE (1<<21)
|
||||
#define HF_RIVER (1<<22)
|
||||
#define HF_MIRROR (1<<23)
|
||||
#define HF_BUG Flag(0)
|
||||
#define HF_EARTH Flag(1)
|
||||
#define HF_BIRD Flag(2)
|
||||
#define HF_LEADER Flag(3)
|
||||
#define HF_HEX Flag(4)
|
||||
#define HF_WHIRLPOOL Flag(5)
|
||||
#define HF_WATER Flag(6)
|
||||
#define HF_AIR Flag(7)
|
||||
#define HF_MUTANT Flag(8)
|
||||
#define HF_OUTLAW Flag(9)
|
||||
#define HF_WHIRLWIND Flag(10)
|
||||
#define HF_ROSE Flag(11)
|
||||
#define HF_DRAGON Flag(12)
|
||||
#define HF_KRAKEN Flag(13)
|
||||
#define HF_SHARK Flag(14)
|
||||
#define HF_BATS Flag(15)
|
||||
#define HF_REPTILE Flag(16)
|
||||
#define HF_EAGLES Flag(17)
|
||||
#define HF_SLOW Flag(18)
|
||||
#define HF_FAST Flag(19)
|
||||
#define HF_WARP Flag(20)
|
||||
#define HF_MOUSE Flag(21)
|
||||
#define HF_RIVER Flag(22)
|
||||
#define HF_MIRROR Flag(23)
|
||||
#define HF_VOID Flag(24)
|
||||
|
||||
bool seenSevenMines = false;
|
||||
|
||||
@ -332,6 +333,7 @@ int* killtable[] = {
|
||||
&kills[moHerdBull], &kills[moSleepBull], &kills[moRagingBull],
|
||||
&kills[moGadfly], &kills[moButterfly],
|
||||
&kills[moNarciss], &kills[moMirrorSpirit],
|
||||
&kills[moHunterDog], &kills[moIceGolem], &kills[moVoidBeast],
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -459,6 +461,7 @@ bool strictlyAgainstGravity(cell *w, cell *from, bool revdir, flagtype flags) {
|
||||
|
||||
bool passable(cell *w, cell *from, flagtype flags) {
|
||||
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;
|
||||
|
||||
@ -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 && !((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_JUMP1 | P_JUMP2 | P_BULLET | P_FLYING | P_BLOW | P_CLIMBUP | P_AETHER | P_REPTILE))
|
||||
return false;
|
||||
@ -483,11 +486,11 @@ bool passable(cell *w, cell *from, flagtype flags) {
|
||||
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)
|
||||
) 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)))
|
||||
return true;
|
||||
@ -621,7 +624,15 @@ void calcAirdir(cell *c) {
|
||||
|
||||
bool againstWind(cell *cto, cell *cfrom) {
|
||||
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);
|
||||
int d = neighborId(cfrom, cto);
|
||||
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);
|
||||
if(isWorm(m))
|
||||
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;
|
||||
}
|
||||
|
||||
@ -805,6 +818,7 @@ eMonster movegroup(eMonster m) {
|
||||
if(m == moWaterElemental) return moWaterElemental;
|
||||
if(m == moAirElemental) return moAirElemental;
|
||||
if(isBull(m)) return moRagingBull;
|
||||
if(m == moVoidBeast) return moVoidBeast;
|
||||
return moNone;
|
||||
}
|
||||
|
||||
@ -959,6 +973,14 @@ bool stalemate1::isKilled(cell *w) {
|
||||
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(canAttack(moveto, who, w, w->monst, AF_STAB))
|
||||
return true;
|
||||
@ -1279,13 +1301,16 @@ int monstersnear(cell *c, cell *nocount, eMonster who, cell *pushto, cell *comef
|
||||
return b;
|
||||
}
|
||||
|
||||
void petrify(cell *c, eWall walltype, eMonster m) {
|
||||
bool petrify(cell *c, eWall walltype, eMonster m) {
|
||||
destroyHalfvine(c);
|
||||
playSound(c, "die-troll");
|
||||
|
||||
if(walltype == waIcewall && !isIcyLand(c->land))
|
||||
return false;
|
||||
|
||||
if(isWateryOrBoat(c) && c->land == laWhirlpool) {
|
||||
c->wall = waSea;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(walltype == waGargoyle && cellUnstableOrChasm(c))
|
||||
@ -1296,11 +1321,11 @@ void petrify(cell *c, eWall walltype, eMonster m) {
|
||||
walltype = waPetrifiedBridge;
|
||||
else if((c->wall == waTempBridge || c->wall == waTempBridgeBlocked) && c->land == laWhirlpool) {
|
||||
c->wall = waTempBridgeBlocked;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
else if(!doesnotFall(c)) {
|
||||
fallingFloorAnimation(c, walltype, m);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(isReptile(c->wall)) kills[moReptile]++;
|
||||
@ -1308,6 +1333,7 @@ void petrify(cell *c, eWall walltype, eMonster m) {
|
||||
c->wall = walltype;
|
||||
c->wparam = m;
|
||||
c->item = itNone;
|
||||
return true;
|
||||
}
|
||||
|
||||
void killIvy(cell *c, eMonster who) {
|
||||
@ -1755,6 +1781,7 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
|
||||
if(isPrincess(m)) m = moPrincess;
|
||||
if(m == moTentacleGhost) m = moGhost;
|
||||
if(!isBulletType(m)) kills[m]++;
|
||||
if(m == moHunterGuard) m = moHunterDog;
|
||||
|
||||
if(!c->item) if(m == moButterfly && (deathflags & AF_BULL))
|
||||
c->item = itBull;
|
||||
@ -1816,6 +1843,12 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
|
||||
|
||||
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) {
|
||||
petrify(c, waDeadTroll, m); pcount = 0;
|
||||
@ -2359,6 +2392,10 @@ bool recalcTide;
|
||||
#define LANDDIST LHU.bytes[1]
|
||||
#define CHAOSPARAM LHU.bytes[2]
|
||||
|
||||
int alchemyval(cell *c, int t) {
|
||||
return (windmap::at(c) + (turncount+t)*4) & 255;
|
||||
}
|
||||
|
||||
void checkTide(cell *c) {
|
||||
if(c->land == laOcean) {
|
||||
int t = c->landparam;
|
||||
@ -2390,6 +2427,11 @@ void checkTide(cell *c) {
|
||||
if(isFire(c) && t >= tidalphase)
|
||||
c->wall = waSea;
|
||||
}
|
||||
if(isAlch2(c, true)) {
|
||||
int id = alchemyval(c, 0);
|
||||
if(id < 96) c->wall = waBubble;
|
||||
else c->wall = waSlime1;
|
||||
}
|
||||
}
|
||||
|
||||
void buildAirmap() {
|
||||
@ -2746,6 +2788,7 @@ void bfs() {
|
||||
else if(isLeader(c2->monst)) havewhat |= HF_LEADER;
|
||||
else if(c2->monst == moEarthElemental) havewhat |= HF_EARTH;
|
||||
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 == moAirElemental)
|
||||
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
|
||||
// this is called from moveMonster, or separately from moveIvy/moveWorm,
|
||||
// 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))
|
||||
toggleGates(ct, ct->wall);
|
||||
|
||||
if(ct->wall == waArrowTrap && !ignoresPlates(m))
|
||||
activateArrowTrap(ct);
|
||||
|
||||
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))
|
||||
toggleGates(c2, c2->wall);
|
||||
|
||||
if(c2->wall == waArrowTrap && !markOrb(itOrbAether))
|
||||
activateArrowTrap(c2);
|
||||
|
||||
princess::playernear(c2);
|
||||
|
||||
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(c->monst == moRagingBull) return -1690; // worse than to stay in place
|
||||
if(c->monst == moBat && batsAfraid(c)) return 575;
|
||||
if(c->monst == moHunterGuard) return 1600; // prefers to stay in place
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@ -3423,8 +3481,11 @@ int determinizeBullPush(cellwalker bull) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int posdir[10], nc;
|
||||
|
||||
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);
|
||||
for(int d=0; d<c->type; d++) {
|
||||
@ -3439,8 +3500,7 @@ int pickMoveDirection(cell *c, flagtype mf) {
|
||||
determinizeBull(c, posdir, nc);
|
||||
|
||||
if(!nc) return -1;
|
||||
nc = hrand(nc);
|
||||
return posdir[nc];
|
||||
return posdir[hrand(nc)];
|
||||
}
|
||||
|
||||
int pickDownDirection(cell *c, flagtype mf) {
|
||||
@ -3523,13 +3583,15 @@ void beastAttack(cell *c, bool player) {
|
||||
}
|
||||
}
|
||||
|
||||
bool quantum;
|
||||
|
||||
cell *moveNormal(cell *c, flagtype mf) {
|
||||
eMonster m = c->monst;
|
||||
|
||||
int d;
|
||||
|
||||
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 {
|
||||
@ -3541,24 +3603,55 @@ cell *moveNormal(cell *c, flagtype mf) {
|
||||
stayEffect(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(m == moRagingBull) beastAttack(c2, false);
|
||||
return c2;
|
||||
if(!quantum) {
|
||||
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(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) {
|
||||
@ -4136,8 +4229,9 @@ void snakeAttack(cell *c, bool mounted) {
|
||||
for(int j=0; j<c->type; j++)
|
||||
if(c->mov[j] && canAttack(c, moHexSnake, c->mov[j], c->mov[j]->monst,
|
||||
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);
|
||||
produceGhost(c->mov[j], moHexSnake, m2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4425,6 +4519,36 @@ void swordAttackStatic() {
|
||||
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) {
|
||||
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);
|
||||
produceGhost(c2, m2, m);
|
||||
sideAttack(c, dir, m, 0);
|
||||
if(revenge) c->monst = m = moPrincessArmed;
|
||||
if(jealous) {
|
||||
playSound(c2, princessgender() ? "dzia-princess" : "dzia-prince");
|
||||
@ -4960,7 +5085,7 @@ void moverefresh(bool turn = true) {
|
||||
if(c->monst == moTortoise && c->item == itBabyTortoise &&
|
||||
!((tortoise::getb(c) ^ tortoise::babymap[c]) & tortoise::mask))
|
||||
c->stuntime = 2;
|
||||
|
||||
|
||||
if(c->monst == moReptile) {
|
||||
if(c->wall == waChasm || cellUnstable(c)) {
|
||||
c->monst = moNone;
|
||||
@ -5166,6 +5291,8 @@ void movemonsters() {
|
||||
if(havewhat & HF_EARTH) groupmove(moEarthElemental, 0);
|
||||
DEBT("water");
|
||||
if(havewhat & HF_WATER) groupmove(moWaterElemental, 0);
|
||||
DEBT("void");
|
||||
if(havewhat & HF_VOID) groupmove(moVoidBeast, 0);
|
||||
DEBT("leader");
|
||||
if(havewhat & HF_LEADER) groupmove(moPirate, 0);
|
||||
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) {
|
||||
|
||||
int pg = gold();
|
||||
@ -5739,6 +6000,11 @@ bool collectItem(cell *c2, bool telekinesis) {
|
||||
if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item);
|
||||
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()) {
|
||||
multiRevival(cwt.c, c2);
|
||||
@ -5874,7 +6140,7 @@ bool collectItem(cell *c2, bool telekinesis) {
|
||||
gainItem(itElemental);
|
||||
gainItem(itElemental);
|
||||
addMessage(XLAT("You construct some Elemental Gems!", c2->item) + itemcounter(items[itElemental]));
|
||||
}
|
||||
}
|
||||
|
||||
if(c2->item == itBounty)
|
||||
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() {
|
||||
mirror::breakAll();
|
||||
DEBT("bfs");
|
||||
@ -6239,7 +6518,8 @@ void monstersTurn() {
|
||||
|
||||
orbbull::check();
|
||||
|
||||
|
||||
terracotta();
|
||||
|
||||
DEBT("check");
|
||||
checkmove();
|
||||
if(canmove) elec::checklightningfast();
|
||||
@ -6559,16 +6839,19 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
||||
addMessage(XLAT("You start chopping down the tree."));
|
||||
playSound(c2, "hit-axe" + pick123());
|
||||
c2->wall = waNone;
|
||||
sideAttack(cwt.c, d, moPlayer, 0);
|
||||
}
|
||||
else if(c2->wall == waBigTree) {
|
||||
drawParticles(c2, winf[c2->wall].color, 8);
|
||||
addMessage(XLAT("You chop down the tree."));
|
||||
playSound(c2, "hit-axe" + pick123());
|
||||
c2->wall = waSmallTree;
|
||||
sideAttack(cwt.c, d, moPlayer, 0);
|
||||
}
|
||||
else {
|
||||
if(!peace::on)
|
||||
if(!peace::on) {
|
||||
addMessage(XLAT("You swing your sword at the mirror."));
|
||||
sideAttack(cwt.c, d, moPlayer, 0);
|
||||
}
|
||||
}
|
||||
if(survivalist && isHaunted(c2->land))
|
||||
survivalist = false;
|
||||
@ -6692,6 +6975,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
||||
}
|
||||
}
|
||||
|
||||
sideAttack(cwt.c, d, moPlayer, 0);
|
||||
lastmovetype = lmAttack; lastmove = c2;
|
||||
swordAttackStatic();
|
||||
}
|
||||
|
166
graph.cpp
166
graph.cpp
@ -403,9 +403,8 @@ void ShadowV(const transmatrix& V, const hpcshape& bp, int prio) {
|
||||
if(mmspatial) {
|
||||
if(pmodel == mdHyperboloid || pmodel == mdBall)
|
||||
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);
|
||||
poly_outline = p;
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,6 +502,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
|
||||
it == itHolyGrail ? &shGrail :
|
||||
isElementalShard(it) ? &shElementalShard :
|
||||
(it == itBombEgg || it == itTrollEgg) ? &shEgg :
|
||||
it == itDogPlains ? &shTriangle :
|
||||
it == itDodeca ? &shDodeca :
|
||||
xch == '*' ? &shGem[ct6] :
|
||||
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)
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
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));
|
||||
}
|
||||
else if(m == moRunDog) {
|
||||
else if(m == moRunDog || m == moHunterDog || m == moHunterGuard) {
|
||||
if(!mmspatial && !footphase)
|
||||
queuepoly(VABODY, shDogBody, darkena(col, 0, 0xFF));
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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)
|
||||
queuepoly(VFISH, shShark, darkena(col, 0, 0xFF));
|
||||
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);
|
||||
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);
|
||||
queuepoly(VBODY, shPBody, c);
|
||||
}
|
||||
else if(m == moTerraWarrior)
|
||||
drawTerraWarrior(V, 7, footphase);
|
||||
else if(m == moDesertman) {
|
||||
otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase);
|
||||
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, 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) {
|
||||
if(m == moFriendlyGhost) col = fghostcolor(ticks, where);
|
||||
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;
|
||||
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) {
|
||||
otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase);
|
||||
ShadowV(V, shYeti);
|
||||
@ -1386,7 +1428,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
||||
int acol = col;
|
||||
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);
|
||||
ShadowV(V, shPBody);
|
||||
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(c->land == laOcean)
|
||||
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));
|
||||
else if(c->land == laOceanWall)
|
||||
@ -2366,11 +2408,6 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
case laCanvas:
|
||||
fcol = c->landparam;
|
||||
break;
|
||||
case laAlchemy2:
|
||||
fcol = (windmap::windcodes[windmap::getId(c)] - SDL_GetTicks()/10) & 255;
|
||||
if(fcol > 128) fcol = 256 - fcol;
|
||||
fcol += 96;
|
||||
break;
|
||||
case laPalace:
|
||||
fcol = 0x806020;
|
||||
if(c->wall == waClosedGate || c->wall == waOpenGate)
|
||||
@ -2422,6 +2459,17 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
fcol = wcol[whirlwind::fzebra3(c)];
|
||||
}
|
||||
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:
|
||||
fcol = 0x10101 * (32 + (c->landparam&1) * 32) - 0x000010;
|
||||
@ -2492,24 +2540,34 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
break;
|
||||
}
|
||||
|
||||
case laIce: case laCocytus:
|
||||
case laIce: case laCocytus: case laBlizzard:
|
||||
if(isIcyWall(c)) {
|
||||
float h = HEAT(c);
|
||||
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)
|
||||
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)
|
||||
wcol = gradient(showcoc ? 0x80C0FF : 0x8080FF, 0xFFFFFF, 0, h, 0.2);
|
||||
wcol = gradient(color0, color02, 0, h, 0.2);
|
||||
// else if(h < 0.4)
|
||||
// wcol = gradient(0xFFFFFF, 0xFFFF00, 0.2, h, 0.4);
|
||||
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)
|
||||
wcol = gradient(0xFF0000, 0xFFFF00, 0.6, h, 0.8);
|
||||
wcol = gradient(color06, color08, 0.6, h, 0.8);
|
||||
else
|
||||
wcol = 0xFFFF00;
|
||||
wcol = color08;
|
||||
if(c->wall == waFrozenLake)
|
||||
fcol = wcol;
|
||||
else
|
||||
@ -2563,6 +2621,15 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
else
|
||||
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) {
|
||||
eMonster m = eMonster(c->wparam);
|
||||
@ -2884,6 +2951,8 @@ bool allemptynear(cell *c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "blizzard.cpp"
|
||||
|
||||
void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
qfi.shape = NULL; qfi.special = false;
|
||||
@ -3160,7 +3229,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
int fd =
|
||||
c->land == laRedRock ? 0 :
|
||||
(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 == laDeadCaves || c->land == laPalace || c->land == laCA ? 1 :
|
||||
c->land == laCanvas ? 0 :
|
||||
@ -3179,7 +3248,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
c->land == laHalloween ? 1 :
|
||||
c->land == laTrollheim ? 2 :
|
||||
c->land == laReptile ? 0 :
|
||||
c->land == laDogPlains ? 1 :
|
||||
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;
|
||||
|
||||
@ -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(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) {
|
||||
qfloor(c, Vf, shBFloor[ct6], darkena(fcol, 0, 0xFF));
|
||||
int rd = rosedist(c);
|
||||
@ -3505,7 +3586,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
else if(c->land == laHell)
|
||||
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));
|
||||
|
||||
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));
|
||||
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;
|
||||
bool magical = items[itOrbWater] && (isPlayerOn(c) || (isFriendly(c) && items[itOrbEmpathy]));
|
||||
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 ||
|
||||
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) {
|
||||
@ -3837,32 +3921,35 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
}
|
||||
else {
|
||||
transmatrix Vdepth = mscale(V, geom3::WALL);
|
||||
int alpha = 0xFF;
|
||||
if(c->wall == waIcewall)
|
||||
alpha = 0xC0;
|
||||
|
||||
bool warp = isWarped(c);
|
||||
|
||||
if(starcol && !(wmescher && c->wall == waPlatform))
|
||||
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);
|
||||
|
||||
if(c->wall == waCamelot) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
|
||||
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 == '%') {
|
||||
if(doHighlight())
|
||||
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 != ',')
|
||||
error = true;
|
||||
}
|
||||
|
||||
else if(!(it || c->monst || c->cpdist == 0)) error = true;
|
||||
|
||||
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) {
|
||||
whirlwind::calcdirs(c);
|
||||
|
||||
@ -4472,6 +4568,7 @@ void drawFlashes() {
|
||||
|
||||
bool allowIncreasedSight() {
|
||||
if(cheater) return true;
|
||||
if(inHighQual) return true;
|
||||
if(peace::on) return true;
|
||||
#if CAP_TOUR
|
||||
if(tour::on) return true;
|
||||
@ -4487,7 +4584,7 @@ void drawthemap() {
|
||||
|
||||
frameid++;
|
||||
|
||||
wavephase = (-(SDL_GetTicks() / 100)) & 7;
|
||||
wavephase = (-(ticks / 100)) & 7;
|
||||
|
||||
if(!allowIncreasedSight()) {
|
||||
if(sightrange > 7) sightrange = 7;
|
||||
@ -4562,6 +4659,7 @@ void drawthemap() {
|
||||
maxreclevel,
|
||||
hsOrigin, ypush(vid.yshift) * sphereflip * View);
|
||||
}
|
||||
drawBlizzards();
|
||||
ivoryz = false;
|
||||
|
||||
linepatterns::drawAll();
|
||||
|
10
hyper.cpp
10
hyper.cpp
@ -150,6 +150,12 @@ int arg::readCommon() {
|
||||
shift(); int q = argi();
|
||||
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")) {
|
||||
PHASE(3) cheater++; timerghost = false;
|
||||
shift(); eMonster m = readMonster(args());
|
||||
@ -272,6 +278,10 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
|
||||
fieldpattern::info();
|
||||
exit(0);
|
||||
}
|
||||
else if(argis("-quantum")) {
|
||||
quantum = true;
|
||||
autocheat = true;
|
||||
}
|
||||
else if(argis("-P")) {
|
||||
PHASE(2); shift();
|
||||
vid.scfg.players = argi();
|
||||
|
141
hyper.h
141
hyper.h
@ -53,7 +53,8 @@ void achievement_pump();
|
||||
vector<string> achievementsReceived;
|
||||
|
||||
// game forward declarations
|
||||
typedef int flagtype;
|
||||
typedef unsigned long long flagtype;
|
||||
#define Flag(i) (flagtype(1ull<<i))
|
||||
|
||||
bool mirrorkill(cell *c);
|
||||
bool isNeighbor(cell *c1, cell *c2);
|
||||
@ -461,38 +462,39 @@ void setGLProjection();
|
||||
|
||||
// passable flags
|
||||
|
||||
#define P_MONSTER (1<<0) // can move through monsters
|
||||
#define P_MIRROR (1<<1) // can move through mirrors
|
||||
#define P_REVDIR (1<<2) // reverse direction movement
|
||||
#define P_WIND (1<<3) // can move against the wind
|
||||
#define P_GRAVITY (1<<4) // can move against the gravity
|
||||
#define P_ISPLAYER (1<<5) // player-only moves (like the Round Table jump)
|
||||
#define P_ONPLAYER (1<<6) // always can step on the player
|
||||
#define P_FLYING (1<<7) // is flying
|
||||
#define P_BULLET (1<<8) // bullet can fly through more things
|
||||
#define P_MIRRORWALL (1<<9) // mirror images go through mirror walls
|
||||
#define P_JUMP1 (1<<10) // first part of a jump
|
||||
#define P_JUMP2 (1<<11) // second part of a jump
|
||||
#define P_TELE (1<<12) // teleport onto
|
||||
#define P_BLOW (1<<13) // Orb of Air -- blow, or push
|
||||
#define P_AETHER (1<<14) // aethereal
|
||||
#define P_FISH (1<<15) // swimming
|
||||
#define P_WINTER (1<<16) // fire resistant
|
||||
#define P_USEBOAT (1<<17) // can use boat
|
||||
#define P_NOAETHER (1<<18) // disable AETHER
|
||||
#define P_FRIENDSWAP (1<<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_LEADER (1<<21) // can push statues and use boats
|
||||
#define P_MARKWATER (1<<22) // mark Orb of Water as used
|
||||
#define P_EARTHELEM (1<<23) // Earth Elemental
|
||||
#define P_WATERELEM (1<<24) // Water Elemental
|
||||
#define P_IGNORE37 (1<<25) // ignore the triheptagonal board
|
||||
#define P_CHAIN (1<<26) // for chaining moves with boats
|
||||
#define P_DEADLY (1<<27) // suicide moves allowed
|
||||
#define P_ROSE (1<<28) // rose smell
|
||||
#define P_CLIMBUP (1<<29) // allow climbing up
|
||||
#define P_CLIMBDOWN (1<<30) // allow climbing down
|
||||
#define P_REPTILE (1<<31) // is reptile
|
||||
#define P_MONSTER Flag(0) // can move through monsters
|
||||
#define P_MIRROR Flag(1) // can move through mirrors
|
||||
#define P_REVDIR Flag(2) // reverse direction movement
|
||||
#define P_WIND Flag(3) // can move against the wind
|
||||
#define P_GRAVITY Flag(4) // can move against the gravity
|
||||
#define P_ISPLAYER Flag(5) // player-only moves (like the Round Table jump)
|
||||
#define P_ONPLAYER Flag(6) // always can step on the player
|
||||
#define P_FLYING Flag(7) // is flying
|
||||
#define P_BULLET Flag(8) // bullet can fly through more things
|
||||
#define P_MIRRORWALL Flag(9) // mirror images go through mirror walls
|
||||
#define P_JUMP1 Flag(10) // first part of a jump
|
||||
#define P_JUMP2 Flag(11) // second part of a jump
|
||||
#define P_TELE Flag(12) // teleport onto
|
||||
#define P_BLOW Flag(13) // Orb of Air -- blow, or push
|
||||
#define P_AETHER Flag(14) // aethereal
|
||||
#define P_FISH Flag(15) // swimming
|
||||
#define P_WINTER Flag(16) // fire resistant
|
||||
#define P_USEBOAT Flag(17) // can use boat
|
||||
#define P_NOAETHER Flag(18) // disable AETHER
|
||||
#define P_FRIENDSWAP Flag(19) // can move on friends (to swap with tem)
|
||||
#define P_ISFRIEND Flag(20) // is a friend (can use Empathy + Winter/Aether/Fish combo)
|
||||
#define P_LEADER Flag(21) // can push statues and use boats
|
||||
#define P_MARKWATER Flag(22) // mark Orb of Water as used
|
||||
#define P_EARTHELEM Flag(23) // Earth Elemental
|
||||
#define P_WATERELEM Flag(24) // Water Elemental
|
||||
#define P_IGNORE37 Flag(25) // ignore the triheptagonal board
|
||||
#define P_CHAIN Flag(26) // for chaining moves with boats
|
||||
#define P_DEADLY Flag(27) // suicide moves allowed
|
||||
#define P_ROSE Flag(28) // rose smell
|
||||
#define P_CLIMBUP Flag(29) // allow climbing up
|
||||
#define P_CLIMBDOWN Flag(30) // allow climbing down
|
||||
#define P_REPTILE Flag(31) // is reptile
|
||||
#define P_VOID Flag(32) // void beast
|
||||
|
||||
bool passable(cell *w, cell *from, flagtype flags);
|
||||
|
||||
@ -646,38 +648,39 @@ bool withRose(cell *cfrom, cell *cto);
|
||||
|
||||
// canAttack/moveval flags
|
||||
|
||||
#define AF_TOUGH (1<<0) // tough attacks: Hyperbugs
|
||||
#define AF_MAGIC (1<<1) // magical attacks: Flash
|
||||
#define AF_STAB (1<<2) // stabbing attacks (usually ignored except Hedgehogs)
|
||||
#define AF_LANCE (1<<3) // lance attacks (used by Lancers)
|
||||
#define AF_ONLY_ENEMY (1<<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_FBUG (1<<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_APPROACH (1<<8) // approach attacks (ignored except Lancers)
|
||||
#define AF_IGNORE_UNARMED (1<<9) // ignore the UNARMED flag
|
||||
#define AF_NOSHIELD (1<<10) // ignore the shielded status
|
||||
#define AF_GETPLAYER (1<<11) // check for player (replace m2 with moPlayer for player position)
|
||||
#define AF_GUN (1<<12) // revolver attack
|
||||
#define AF_FAST (1<<13) // fast attack
|
||||
#define AF_EAT (1<<17) // eating attacks from Worm-likes
|
||||
#define AF_TOUGH Flag(0) // tough attacks: Hyperbugs
|
||||
#define AF_MAGIC Flag(1) // magical attacks: Flash
|
||||
#define AF_STAB Flag(2) // stabbing attacks (usually ignored except Hedgehogs)
|
||||
#define AF_LANCE Flag(3) // lance attacks (used by Lancers)
|
||||
#define AF_ONLY_ENEMY Flag(4) // only say YES if it is an enemy
|
||||
#define AF_ONLY_FRIEND Flag(5) // only say YES if it is a friend
|
||||
#define AF_ONLY_FBUG Flag(6) // only say YES if it is a bug_or friend
|
||||
#define AF_BACK Flag(7) // backward attacks (ignored except Viziers and Flailers)
|
||||
#define AF_APPROACH Flag(8) // approach attacks (ignored except Lancers)
|
||||
#define AF_IGNORE_UNARMED Flag(9) // ignore the UNARMED flag
|
||||
#define AF_NOSHIELD Flag(10) // ignore the shielded status
|
||||
#define AF_GETPLAYER Flag(11) // check for player (replace m2 with moPlayer for player position)
|
||||
#define AF_GUN Flag(12) // revolver attack
|
||||
#define AF_FAST Flag(13) // fast attack
|
||||
#define AF_EAT Flag(17) // eating attacks from Worm-likes
|
||||
|
||||
#define MF_NOATTACKS (1<<14) // don't do any attacks
|
||||
#define MF_PATHDIST (1<<15) // consider pathdist for moveval
|
||||
#define MF_ONLYEAGLE (1<<16) // do this only for Eagles
|
||||
#define MF_MOUNT (1<<18) // don't do
|
||||
#define MF_NOFRIEND (1<<19) // don't do it for friends
|
||||
#define MF_NOATTACKS Flag(14) // don't do any attacks
|
||||
#define MF_PATHDIST Flag(15) // consider pathdist for moveval
|
||||
#define MF_ONLYEAGLE Flag(16) // do this only for Eagles
|
||||
#define MF_MOUNT Flag(18) // don't do
|
||||
#define MF_NOFRIEND Flag(19) // don't do it for friends
|
||||
|
||||
#define AF_SWORD (1<<20) // big sword
|
||||
#define AF_SWORD_INTO (1<<21) // moving into big sword
|
||||
#define AF_MSG (1<<22) // produce a message
|
||||
#define AF_ORSTUN (1<<23) // attackMonster: allow stunning
|
||||
#define AF_NEXTTURN (1<<24) // next turn -- don't count shield at power 1
|
||||
#define AF_FALL (1<<25) // death by falling
|
||||
#define MF_STUNNED (1<<26) // edgeunstable: ignore ladders (as stunned monsters do)
|
||||
#define MF_IVY (1<<27) // edgeunstable: ignore ivy (ivy cannot climb ivy)
|
||||
#define AF_HORNS (1<<28) // spear attack (always has APPROACH too)
|
||||
#define AF_BULL (1<<29) // bull attack
|
||||
#define AF_SWORD Flag(20) // big sword
|
||||
#define AF_SWORD_INTO Flag(21) // moving into big sword
|
||||
#define AF_MSG Flag(22) // produce a message
|
||||
#define AF_ORSTUN Flag(23) // attackMonster: allow stunning
|
||||
#define AF_NEXTTURN Flag(24) // next turn -- don't count shield at power 1
|
||||
#define AF_FALL Flag(25) // death by falling
|
||||
#define MF_STUNNED Flag(26) // edgeunstable: ignore ladders (as stunned monsters do)
|
||||
#define MF_IVY Flag(27) // edgeunstable: ignore ivy (ivy cannot climb ivy)
|
||||
#define AF_HORNS Flag(28) // spear attack (always has APPROACH too)
|
||||
#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);
|
||||
|
||||
@ -857,7 +860,7 @@ void resetGeometry();
|
||||
|
||||
namespace svg {
|
||||
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);
|
||||
extern bool in;
|
||||
extern string *info;
|
||||
@ -1533,6 +1536,16 @@ static bool orbProtection(eItem it) { return false; } // not implemented
|
||||
|
||||
namespace windmap {
|
||||
void create();
|
||||
|
||||
static const int NOWINDBELOW = 8;
|
||||
static const int NOWINDFROM = 120;
|
||||
|
||||
int at(cell *c);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -311,7 +320,11 @@ eItem treasureType(eLand l) {
|
||||
case laBull: return itBull;
|
||||
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;
|
||||
}
|
||||
return itNone;
|
||||
@ -767,6 +780,15 @@ bool landUnlocked(eLand l) {
|
||||
case laAlchemy2:
|
||||
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:
|
||||
return gold() >= R300;
|
||||
}
|
||||
@ -3512,6 +3534,15 @@ int reptilemax() {
|
||||
|
||||
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!
|
||||
void setdist(cell *c, int d, cell *from) {
|
||||
|
||||
@ -3611,7 +3642,7 @@ void setdist(cell *c, int d, cell *from) {
|
||||
else buildPrizeMirror(c, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(d == 7)
|
||||
prairie::generateTreasure(c);
|
||||
|
||||
@ -3986,7 +4017,55 @@ void setdist(cell *c, int d, cell *from) {
|
||||
|
||||
if(c->land == laAlchemist)
|
||||
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(randomPatternsMode)
|
||||
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)
|
||||
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(items[itFjord] >= 5 && hrand(100) < 20 && !peace::on)
|
||||
@ -4821,7 +4917,7 @@ void setdist(cell *c, int d, cell *from) {
|
||||
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;
|
||||
|
||||
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))
|
||||
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(hrand(8000) < items[itTrollEgg] + hardness_empty())
|
||||
@ -5482,7 +5599,7 @@ void setdist(cell *c, int d, cell *from) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool wchance(int a, int of) {
|
||||
bool wchance(int a, int of, int reduction = 0) {
|
||||
of *= 10;
|
||||
a += yendor::hardness() + 1;
|
||||
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)
|
||||
a = max(a, (items[i]-R10) / 10);
|
||||
|
||||
a -= reduction;
|
||||
if(a < 0) return false;
|
||||
|
||||
return hrand(a+of) < a;
|
||||
}
|
||||
|
||||
@ -5721,6 +5842,9 @@ void wandering() {
|
||||
else if(c->land == laIce && wchance(items[itDiamond], 10))
|
||||
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))
|
||||
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;
|
||||
}
|
||||
else {
|
||||
cwspin(lig, 3);
|
||||
if(c->type == 7) cwspin(lig, hrand(2));
|
||||
cwrev(lig);
|
||||
}
|
||||
|
||||
if(lig.c->wall == waCloud) {
|
||||
@ -654,8 +653,6 @@ eMonster summonedAt(cell *dest) {
|
||||
return dest->land == laPalace ? moPalace : moBat;
|
||||
if(dest->wall == waFloorA || dest->wall == waFloorB)
|
||||
return moSlime;
|
||||
if(dest->wall == waFloorC || dest->wall == waFloorD)
|
||||
return moRatling;
|
||||
if(dest->wall == waCavefloor)
|
||||
return moTroll;
|
||||
if(dest->wall == waDeadfloor)
|
||||
@ -698,6 +695,7 @@ eMonster summonedAt(cell *dest) {
|
||||
if(dest->wall == waGiantRug)
|
||||
return moVizier;
|
||||
if(dest->wall == waNone) {
|
||||
if(dest->land == laDogPlains) return moAirElemental;
|
||||
if(dest->land == laBull) return moRagingBull;
|
||||
if(dest->land == laPrairie) return moAirElemental;
|
||||
if(dest->land == laZebra) return moAirElemental;
|
||||
|
Loading…
Reference in New Issue
Block a user