mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
Magnetic and Switch V1
This commit is contained in:
parent
9948b09b69
commit
d3e789bc93
12
classes.cpp
12
classes.cpp
@ -757,6 +757,10 @@ monstertype minf[motypes] = {
|
||||
"are stunned for a longer time if you push them into lava, fire, or a solid obstacle."},
|
||||
{ 'W', 0x202020, "Hunting Dog (regrouping)",
|
||||
"When your plan has clearly failed, it is better to abandon it and go to a safe place, to have a chance of succeeding next time. This dog clearly knows this."},
|
||||
{ 'B', 0xC00000, "North Pole", NODESCYET},
|
||||
{ 'B', 0x0000C0, "South Pole", NODESCYET},
|
||||
{ '@', 0xC00000, "Switcher A", NODESCYET},
|
||||
{ '@', 0x0000C0, "Switcher B", NODESCYET},
|
||||
|
||||
// shmup specials
|
||||
{ '@', 0xC0C0C0, "Rogue", "In the Shoot'em Up mode, you are armed with thrown Knives."},
|
||||
@ -1203,8 +1207,10 @@ itemtype iinf[ittypes] = {
|
||||
"Does not affect multi-tile monsters."},
|
||||
{ '!', 0x80FF00, "Glowing Crystal", crystaldesc},
|
||||
{ '!', 0x80FF80, "Snake Oil", NODESCYET},
|
||||
{ '*', 0x80FF80, "Dock Treasure", NODESCYET},
|
||||
{ '*', 0x80FF80, "Sea Glass", NODESCYET},
|
||||
{ '*', 0x80FF80, "Invix Treasure", NODESCYET},
|
||||
{ '*', 0x80FF80, "Monopole", NODESCYET},
|
||||
{ '*', 0xFFFF80, "Junk", NODESCYET},
|
||||
};
|
||||
|
||||
// --- wall types ---
|
||||
@ -1571,7 +1577,9 @@ const landtype linf[landtypes] = {
|
||||
{ 0x80FF00, "Crystal World", crystaldesc},
|
||||
{ 0x306030, "Snake Nest", NODESCYET},
|
||||
{ 0x80FF00, "Docks", NODESCYET},
|
||||
{ 0x306030, "Invisible", NODESCYET},
|
||||
{ 0x306030, "Invincible", NODESCYET},
|
||||
{ 0x306030, "Magnetosphere", NODESCYET},
|
||||
{ 0x306030, "Switch", NODESCYET},
|
||||
};
|
||||
|
||||
struct landtacinfo { eLand l; int tries, multiplier; };
|
||||
|
13
classes.h
13
classes.h
@ -1,4 +1,4 @@
|
||||
static const int motypes = 152;
|
||||
static const int motypes = 156;
|
||||
|
||||
struct monstertype {
|
||||
char glyph;
|
||||
@ -52,6 +52,8 @@ enum eMonster {
|
||||
moButterfly, moNarciss, moMirrorSpirit,
|
||||
moHunterDog, moTerraWarrior, moJiangshi, moVoidBeast, moLavaWolf, moHunterGuard,
|
||||
moIceGolem, moSandBird, moSalamander, moHunterChanging,
|
||||
moNorthPole, moSouthPole,
|
||||
moSwitch1, moSwitch2,
|
||||
// shmup specials
|
||||
moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball,
|
||||
// temporary
|
||||
@ -68,7 +70,7 @@ struct genderswitch_t {
|
||||
|
||||
#define NUM_GS 6
|
||||
|
||||
static const int ittypes = 125;
|
||||
static const int ittypes = 127;
|
||||
|
||||
struct itemtype {
|
||||
char glyph;
|
||||
@ -113,7 +115,7 @@ enum eItem {
|
||||
itLavaLily, itHunting, itBlizzard, itTerra,
|
||||
itOrbSide1, itOrbSide2, itOrbSide3,
|
||||
itOrbLava, itOrbMorph, itGlowCrystal, itSnake,
|
||||
itDock, itInvix
|
||||
itDock, itInvix, itMagnet, itSwitch
|
||||
};
|
||||
|
||||
static const int walltypes = 107;
|
||||
@ -160,7 +162,7 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
|
||||
waDock, waBurningDock
|
||||
};
|
||||
|
||||
static const int landtypes = 81;
|
||||
static const int landtypes = 83;
|
||||
|
||||
struct landtype {
|
||||
int color;
|
||||
@ -186,7 +188,8 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
|
||||
laMirrorWall, laMirrored, laMirrorWall2, laMirrored2,
|
||||
laMirrorOld,
|
||||
laVolcano, laBlizzard, laHunting, laTerracotta, laMercuryRiver,
|
||||
laDual, laSnakeNest, laDocks, laInvincible
|
||||
laDual, laSnakeNest, laDocks, laInvincible, laMagnetic,
|
||||
laSwitch
|
||||
};
|
||||
|
||||
enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gGUARD};
|
||||
|
16
flags.cpp
16
flags.cpp
@ -276,7 +276,7 @@ int itemclass(eItem i) {
|
||||
i == itGreenGrass || i == itBull ||
|
||||
i == itLavaLily || i == itHunting ||
|
||||
i == itBlizzard || i == itTerra || i == itGlowCrystal || i == itSnake ||
|
||||
i == itDock || i == itInvix
|
||||
i == itDock || i == itInvix || i == itSwitch
|
||||
)
|
||||
return IC_TREASURE;
|
||||
if(i == itSavedPrincess || i == itStrongWind || i == itWarning)
|
||||
@ -385,7 +385,18 @@ bool normalMover(eMonster m) {
|
||||
m == moHunterDog || m == moTerraWarrior || m == moJiangshi ||
|
||||
m == moLavaWolf || m == moSalamander ||
|
||||
m == moHunterGuard || m == moHunterChanging ||
|
||||
m == moIceGolem || slowMover(m);
|
||||
m == moIceGolem ||
|
||||
m == moNorthPole || m == moSouthPole ||
|
||||
m == moSwitch1 || m == moSwitch2 ||
|
||||
slowMover(m);
|
||||
}
|
||||
|
||||
bool isMagneticPole(eMonster m) {
|
||||
return m == moNorthPole || m == moSouthPole;
|
||||
}
|
||||
|
||||
bool isSwitch(eMonster m) {
|
||||
return m == moSwitch1 || m == moSwitch2;
|
||||
}
|
||||
|
||||
// from-to
|
||||
@ -494,6 +505,7 @@ bool isInactiveEnemy(cell *w, eMonster forwho) {
|
||||
bool isActiveEnemy(cell *w, eMonster forwho) {
|
||||
if(((forwho == moPlayer) ? realstuntime(w) : realstuntime(w) > 1))
|
||||
return false;
|
||||
if(w->monst == passive_switch) return false;
|
||||
if(w->monst == moNone) return false;
|
||||
if(isFriendly(w)) return false;
|
||||
if(isInactiveEnemy(w, forwho)) return false;
|
||||
|
39
game.cpp
39
game.cpp
@ -728,12 +728,28 @@ void moveBoatIfUsingOne(cell *to, cell *from) {
|
||||
}
|
||||
}
|
||||
|
||||
bool againstMagnet(cell *c1, cell *c2) { // (from, to)
|
||||
if(!isMagneticPole(c1->monst))
|
||||
return false;
|
||||
forCellEx(c3, c2)
|
||||
if(c3 != c1 && c3->monst == c1->monst)
|
||||
return true;
|
||||
forCellEx(c3, c1)
|
||||
if(c3->monst != c1->monst && isMagneticPole(c3->monst))
|
||||
if(!isNeighbor(c3, c2))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool passable_for(eMonster m, cell *w, cell *from, flagtype extra) {
|
||||
if(w->monst && !(extra & P_MONSTER) && !isPlayerOn(w))
|
||||
return false;
|
||||
if(m == moWolf) {
|
||||
return (isIcyLand(w) || w->land == laVolcano) && (isPlayerOn(w) || passable(w, from, extra));
|
||||
}
|
||||
if(isMagneticPole(m) && w && from && againstMagnet(from, w))
|
||||
return false;
|
||||
if(m == passive_switch) return false;
|
||||
if(normalMover(m) || isBug(m) || isDemon(m) || m == moHerdBull) {
|
||||
if((isWitch(m) || m == moEvilGolem) && w->land != laPower && w->land != laHalloween)
|
||||
return false;
|
||||
@ -866,6 +882,8 @@ bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) {
|
||||
// cannot eat worms
|
||||
if((flags & AF_EAT) && isWorm(m2)) return false;
|
||||
|
||||
if(m1 == passive_switch || m2 == passive_switch) return false;
|
||||
|
||||
if((flags & AF_GETPLAYER) && isPlayerOn(c2)) m2 = moPlayer;
|
||||
|
||||
if(!m2) return false;
|
||||
@ -1095,6 +1113,10 @@ bool krakensafe(cell *c) {
|
||||
(c->item == itOrbFish && c->wall == waBoat) ||
|
||||
(c->item == itOrbAether && c->wall == waBoat);
|
||||
}
|
||||
|
||||
eMonster active_switch() {
|
||||
return eMonster(passive_switch ^ moSwitch1 ^ moSwitch2);
|
||||
}
|
||||
|
||||
int monstersnear(stalemate1& sm) {
|
||||
|
||||
@ -1102,6 +1124,10 @@ int monstersnear(stalemate1& sm) {
|
||||
bool eaten = false;
|
||||
|
||||
if(hardcore && sm.who == moPlayer) return 0;
|
||||
dynamicval<eMonster> sw(passive_switch, passive_switch);
|
||||
if(sm.moveto->item && itemclass(sm.moveto->item) == IC_TREASURE)
|
||||
passive_switch = active_switch();
|
||||
|
||||
int res = 0;
|
||||
bool fast = false;
|
||||
|
||||
@ -3201,7 +3227,7 @@ void makeTrollFootprints(cell *c) {
|
||||
}
|
||||
|
||||
void moveMonster(cell *ct, cell *cf) {
|
||||
eMonster m = cf->monst;
|
||||
eMonster m = cf->monst;
|
||||
bool fri = isFriendly(cf);
|
||||
if(isDragon(m)) {
|
||||
printf("called for Dragon\n");
|
||||
@ -3232,6 +3258,14 @@ void moveMonster(cell *ct, cell *cf) {
|
||||
ct->hitpoints = cf->hitpoints;
|
||||
ct->stuntime = cf->stuntime;
|
||||
|
||||
if(isMagneticPole(m)) {
|
||||
cell *other_pole = cf->mov[cf->mondir];
|
||||
if(other_pole) {
|
||||
ct->mondir = neighborId(ct, other_pole),
|
||||
other_pole->mondir = neighborId(other_pole, ct);
|
||||
}
|
||||
}
|
||||
|
||||
if(fri || isBug(m) || items[itOrbDiscord]) stabbingAttack(cf, ct, m);
|
||||
|
||||
if(isLeader(m)) {
|
||||
@ -6787,7 +6821,10 @@ void terracotta() {
|
||||
}
|
||||
}
|
||||
|
||||
eMonster passive_switch;
|
||||
|
||||
void monstersTurn() {
|
||||
passive_switch = (gold() & 1) ? moSwitch1 : moSwitch2;
|
||||
mirror::breakAll();
|
||||
DEBT("bfs");
|
||||
bfs();
|
||||
|
18
graph.cpp
18
graph.cpp
@ -1212,6 +1212,13 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
||||
if(!peace::on) queuepoly(VBODY, shPSword, 0xFFFF00FF);
|
||||
queuepoly(VHEAD, shHood, 0xD0D000C0);
|
||||
}
|
||||
else if(isSwitch(m)) {
|
||||
otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase);
|
||||
ShadowV(V, shPBody);
|
||||
queuepoly(VBODY, shPBody, darkena(col, 0, 0xC0));
|
||||
if(!peace::on) queuepoly(VBODY, shPSword, 0xFFFF00FF);
|
||||
queuepoly(VHEAD, shHood, darkena(col, 0, 0xFF));
|
||||
}
|
||||
else if(m == moPalace || m == moFatGuard || m == moVizier || m == moSkeleton) {
|
||||
queuepoly(VBODY, shSabre, 0xFFFFFFFF);
|
||||
if(m == moSkeleton) {
|
||||
@ -1537,6 +1544,11 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou
|
||||
if(xch == 'D') acol = 0xD0D0D0;
|
||||
queuepoly(VHEAD, shDemon, darkena(acol, 0, 0xFF));
|
||||
}
|
||||
else if(isMagneticPole(m)) {
|
||||
if(m == moNorthPole)
|
||||
queuepolyat(VBODY * spin(M_PI), shTentacle, 0x000000C0, PPR_TENTACLE1);
|
||||
queuepolyat(VBODY, shDisk, darkena(col, 0, 0xFF), PPR_MONSTER_BODY);
|
||||
}
|
||||
else if(isMetalBeast(m)) {
|
||||
ShadowV(V, shTrylobite);
|
||||
if(!mmspatial)
|
||||
@ -1916,7 +1928,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
||||
// golems, knights, and hyperbugs don't face the player (mondir-controlled)
|
||||
// also whatever in the lineview mode
|
||||
|
||||
else if(isFriendly(c) || isBug(c) || (c->monst && conformal::on) || c->monst == moKrakenH || (isBull(c->monst) && c->mondir != NODIR) || c->monst == moButterfly) {
|
||||
else if(isFriendly(c) || isBug(c) || (c->monst && conformal::on) || c->monst == moKrakenH || (isBull(c->monst) && c->mondir != NODIR) || c->monst == moButterfly || isMagneticPole(c->monst) ||
|
||||
isSwitch(c->monst)) {
|
||||
if(c->monst == moKrakenH) Vs = Vb, nospins = nospinb;
|
||||
if(!nospins) Vs = Vs * ddspin(c, c->mondir, S42);
|
||||
if(isFriendly(c)) drawPlayerEffects(Vs, c, false);
|
||||
@ -2573,6 +2586,9 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
||||
if(c->bardir == NOBARRIERS && c->barleft)
|
||||
fcol = minf[moBug0+c->barright].color;
|
||||
break;
|
||||
case laSwitch:
|
||||
fcol = minf[passive_switch].color;
|
||||
break;
|
||||
case laTortoise:
|
||||
fcol = tortoise::getMatchColor(getBits(c));
|
||||
if(c->wall == waBigTree) wcol = 0x709000;
|
||||
|
3
hyper.h
3
hyper.h
@ -2425,3 +2425,6 @@ extern bool need_mouseh;
|
||||
extern int whateveri, whateveri2;
|
||||
|
||||
void clear_euland(eLand first);
|
||||
|
||||
extern eMonster passive_switch;
|
||||
|
||||
|
26
landgen.cpp
26
landgen.cpp
@ -651,6 +651,15 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
}
|
||||
break;
|
||||
|
||||
case laSwitch:
|
||||
ONEMPTY {
|
||||
if(hrand(5000) < PT(100 + 2 * (kills[moSwitch1] + kills[moSwitch2]), 200) && notDippingFor(itSwitch))
|
||||
c->item = itSwitch;
|
||||
if(hrand(8000) < 40 + 5 * (items[itSwitch] + yendor::hardness()))
|
||||
c->monst = hrand(2) ? moSwitch1 : moSwitch2;
|
||||
}
|
||||
break;
|
||||
|
||||
case laDragon:
|
||||
if(d == 9) {
|
||||
int cd = getCdata(c, 3);
|
||||
@ -1876,6 +1885,23 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
}
|
||||
break;
|
||||
|
||||
case laMagnetic:
|
||||
if(d == 8) {
|
||||
if(hrand(10000) < 30 && !c->monst && !c->wall) {
|
||||
cell *c1 = c;
|
||||
cell *c2 = createMov(c1, hrand(c1->type));
|
||||
if(c2->monst || c2->wall) return;
|
||||
if(hrand(2)) swap(c1, c2);
|
||||
forCellEx(c3, c1) if(c3->monst == moNorthPole) return;
|
||||
forCellEx(c3, c2) if(c3->monst == moSouthPole) return;
|
||||
c1->monst = moNorthPole;
|
||||
c2->monst = moSouthPole;
|
||||
c1->mondir = neighborId(c1, c2);
|
||||
c2->mondir = neighborId(c2, c1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case laDocks: {
|
||||
if(d == 8) {
|
||||
patterns::patterninfo si;
|
||||
|
11
landlock.cpp
11
landlock.cpp
@ -208,6 +208,9 @@ int isNative(eLand l, eMonster m) {
|
||||
|
||||
case laDocks:
|
||||
return among(m, moRatling, moPirate, moCShark, moAlbatross, moFireFairy) ? 2 : 0;
|
||||
|
||||
case laSwitch:
|
||||
return m == moSwitch1 || m == moSwitch2 ? 2 : 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -303,6 +306,7 @@ eItem treasureType(eLand l) {
|
||||
case laSnakeNest: return itSnake;
|
||||
case laDocks: return itDock;
|
||||
case laInvincible: return itInvix;
|
||||
case laSwitch: return itSwitch;
|
||||
|
||||
case laCA: return itNone;
|
||||
}
|
||||
@ -535,6 +539,9 @@ bool landUnlocked(eLand l) {
|
||||
case laDual:
|
||||
case laSnakeNest:
|
||||
return gold() >= R90;
|
||||
|
||||
case laSwitch:
|
||||
return gold() >= R90;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -949,9 +956,9 @@ vector<eLand> land_over = {
|
||||
laPrairie, laBull, laTerracotta, laRose,
|
||||
laElementalWall, laTrollheim,
|
||||
laHell, laCrossroads3, laCocytus, laPower, laCrossroads4,
|
||||
laCrossroads5,
|
||||
laCrossroads5,
|
||||
// EXTRA
|
||||
laWildWest, laHalloween, laDual, laSnakeNest, laDocks, laInvincible, laCA
|
||||
laWildWest, laHalloween, laDual, laSnakeNest, laDocks, laInvincible, laSwitch, laMagnetic, laCA
|
||||
};
|
||||
|
||||
vector<eLand> landlist;
|
||||
|
Loading…
Reference in New Issue
Block a user