mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
Orb of Magnetism. Orb of Phasing. Also fixed Aether in Whirlpool.
This commit is contained in:
parent
3d4e7f501a
commit
9d1fe00d8f
@ -1211,6 +1211,9 @@ itemtype iinf[ittypes] = {
|
|||||||
{ '*', 0x80FF80, "Invix Treasure", NODESCYET},
|
{ '*', 0x80FF80, "Invix Treasure", NODESCYET},
|
||||||
{ '*', 0x80FF80, "Monopole", NODESCYET},
|
{ '*', 0x80FF80, "Monopole", NODESCYET},
|
||||||
{ '*', 0xFFFF80, "Junk", NODESCYET},
|
{ '*', 0xFFFF80, "Junk", NODESCYET},
|
||||||
|
{ 'o', 0x80FF80, "Orb of Phasing", NODESCYET},
|
||||||
|
{ 'o', 0xFFFF80, "Orb of Magnetism", NODESCYET},
|
||||||
|
{ 'o', 0xFFFF80, "Orb of Destruction", NODESCYET},
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- wall types ---
|
// --- wall types ---
|
||||||
|
@ -70,7 +70,7 @@ struct genderswitch_t {
|
|||||||
|
|
||||||
#define NUM_GS 6
|
#define NUM_GS 6
|
||||||
|
|
||||||
static const int ittypes = 127;
|
static const int ittypes = 130;
|
||||||
|
|
||||||
struct itemtype {
|
struct itemtype {
|
||||||
char glyph;
|
char glyph;
|
||||||
@ -115,7 +115,8 @@ enum eItem {
|
|||||||
itLavaLily, itHunting, itBlizzard, itTerra,
|
itLavaLily, itHunting, itBlizzard, itTerra,
|
||||||
itOrbSide1, itOrbSide2, itOrbSide3,
|
itOrbSide1, itOrbSide2, itOrbSide3,
|
||||||
itOrbLava, itOrbMorph, itGlowCrystal, itSnake,
|
itOrbLava, itOrbMorph, itGlowCrystal, itSnake,
|
||||||
itDock, itInvix, itMagnet, itSwitch
|
itDock, itInvix, itMagnet, itSwitch,
|
||||||
|
itOrbPhasing, itOrbMagnetism, itOrbDestruction
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int walltypes = 107;
|
static const int walltypes = 107;
|
||||||
|
@ -139,8 +139,7 @@ namespace whirlwind {
|
|||||||
animateMovement(whirlline[i+1], whirlline[i], LAYER_BOAT);
|
animateMovement(whirlline[i+1], whirlline[i], LAYER_BOAT);
|
||||||
}
|
}
|
||||||
for(int i=0; i<z; i++)
|
for(int i=0; i<z; i++)
|
||||||
if(isPlayerOn(whirlline[i]) && whirlline[i]->item)
|
pickupMovedItems(whirlline[i]);
|
||||||
collectItem(whirlline[i], true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void move() {
|
void move() {
|
||||||
@ -985,6 +984,8 @@ namespace whirlpool {
|
|||||||
if(wfrom->item == itKey || wfrom->item == itOrbYendor)
|
if(wfrom->item == itKey || wfrom->item == itOrbYendor)
|
||||||
for(int i=0; i<wto->type; i++) createMov(wto, i);
|
for(int i=0; i<wto->type; i++) createMov(wto, i);
|
||||||
moveItem(wfrom, wto, false);
|
moveItem(wfrom, wto, false);
|
||||||
|
pickupMovedItems(wfrom);
|
||||||
|
pickupMovedItems(wto);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wto && !wfrom)
|
if(wto && !wfrom)
|
||||||
|
@ -548,7 +548,7 @@ bool haveRangedOrb() {
|
|||||||
items[itOrbFrog] || items[itOrbSummon] || items[itOrbMatter] ||
|
items[itOrbFrog] || items[itOrbSummon] || items[itOrbMatter] ||
|
||||||
items[itRevolver] || items[itOrbStunning] || items[itStrongWind] ||
|
items[itRevolver] || items[itOrbStunning] || items[itStrongWind] ||
|
||||||
items[itOrbDomination] || items[itOrbNature] || items[itOrbDash] ||
|
items[itOrbDomination] || items[itOrbNature] || items[itOrbDash] ||
|
||||||
items[itOrbMorph];
|
items[itOrbMorph] || items[itOrbPhasing];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isOffensiveOrb(eItem it) {
|
bool isOffensiveOrb(eItem it) {
|
||||||
|
44
game.cpp
44
game.cpp
@ -1127,6 +1127,9 @@ int monstersnear(stalemate1& sm) {
|
|||||||
dynamicval<eMonster> sw(passive_switch, passive_switch);
|
dynamicval<eMonster> sw(passive_switch, passive_switch);
|
||||||
if(sm.moveto->item && itemclass(sm.moveto->item) == IC_TREASURE)
|
if(sm.moveto->item && itemclass(sm.moveto->item) == IC_TREASURE)
|
||||||
passive_switch = active_switch();
|
passive_switch = active_switch();
|
||||||
|
if(items[itOrbMagnetism]) forCellEx(c2, sm.moveto)
|
||||||
|
if(canPickupItemWithMagnetism(c2, sm.comefrom) && itemclass(c2->item) == IC_TREASURE)
|
||||||
|
passive_switch = active_switch();
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
bool fast = false;
|
bool fast = false;
|
||||||
@ -3177,6 +3180,16 @@ void playerMoveEffects(cell *c1, cell *c2) {
|
|||||||
addMessage(XLAT("Better not to let your greed make you stray from your path."));
|
addMessage(XLAT("Better not to let your greed make you stray from your path."));
|
||||||
playSound(c2, "nervous");
|
playSound(c2, "nervous");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(items[itOrbMagnetism])
|
||||||
|
forCellEx(c3, c2) if(canPickupItemWithMagnetism(c3, c2)) {
|
||||||
|
if(c3->item == itCompass) {
|
||||||
|
if(!c2->item)
|
||||||
|
moveItem(c3, c2, false);
|
||||||
|
}
|
||||||
|
else if(markOrb(itOrbMagnetism))
|
||||||
|
collectItem(c3, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void beastcrash(cell *c, cell *beast) {
|
void beastcrash(cell *c, cell *beast) {
|
||||||
@ -6292,12 +6305,33 @@ int ambush(cell *c, eItem what) {
|
|||||||
return dogs + dogs0;
|
return dogs + dogs0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cannotPickupItem(cell *c, bool telekinesis) {
|
||||||
|
return itemHidden(c) && !telekinesis && !(isWatery(c) && markOrb(itOrbFish));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canPickupItemWithMagnetism(cell *c, cell *from) {
|
||||||
|
if(!c->item || c->item == itOrbYendor || isWall(c) || cannotPickupItem(c, false))
|
||||||
|
return false;
|
||||||
|
if(c->item == itCompass && from->item)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pickupMovedItems(cell *c) {
|
||||||
|
if(!c->item) return;
|
||||||
|
if(isPlayerOn(c)) collectItem(c, true);
|
||||||
|
if(items[itOrbMagnetism])
|
||||||
|
forCellEx(c2, c)
|
||||||
|
if(isPlayerOn(c2) && canPickupItemWithMagnetism(c, c2))
|
||||||
|
collectItem(c, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool collectItem(cell *c2, bool telekinesis) {
|
bool collectItem(cell *c2, bool telekinesis) {
|
||||||
|
|
||||||
int pg = gold();
|
int pg = gold();
|
||||||
bool dopickup = true;
|
bool dopickup = true;
|
||||||
|
|
||||||
if(itemHidden(c2) && !telekinesis && !(isWatery(c2) && markOrb(itOrbFish)))
|
if(cannotPickupItem(c2, telekinesis))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* if(c2->item == itHolyGrail && telekinesis)
|
/* if(c2->item == itHolyGrail && telekinesis)
|
||||||
@ -6823,8 +6857,12 @@ void terracotta() {
|
|||||||
|
|
||||||
eMonster passive_switch;
|
eMonster passive_switch;
|
||||||
|
|
||||||
void monstersTurn() {
|
void checkSwitch() {
|
||||||
passive_switch = (gold() & 1) ? moSwitch1 : moSwitch2;
|
passive_switch = (gold() & 1) ? moSwitch1 : moSwitch2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void monstersTurn() {
|
||||||
|
checkSwitch();
|
||||||
mirror::breakAll();
|
mirror::breakAll();
|
||||||
DEBT("bfs");
|
DEBT("bfs");
|
||||||
bfs();
|
bfs();
|
||||||
@ -7099,7 +7137,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(againstCurrent(c2, cwt.c) && !markOrb(itOrbWater)) {
|
if(againstCurrent(c2, cwt.c) && !markOrb(itOrbWater)) {
|
||||||
if(markOrb(itOrbFish)) goto escape;
|
if(markOrb(itOrbFish) || markOrb(itOrbAether)) goto escape;
|
||||||
if(!checkonly)
|
if(!checkonly)
|
||||||
addMessage(XLAT("You cannot go against the current!"));
|
addMessage(XLAT("You cannot go against the current!"));
|
||||||
return false;
|
return false;
|
||||||
|
4
hyper.h
4
hyper.h
@ -823,6 +823,7 @@ void setGLProjection();
|
|||||||
#define P_CLIMBDOWN Flag(30) // allow climbing down
|
#define P_CLIMBDOWN Flag(30) // allow climbing down
|
||||||
#define P_REPTILE Flag(31) // is reptile
|
#define P_REPTILE Flag(31) // is reptile
|
||||||
#define P_VOID Flag(32) // void beast
|
#define P_VOID Flag(32) // void beast
|
||||||
|
#define P_PHASE Flag(33) // phasing movement
|
||||||
|
|
||||||
bool passable(cell *w, cell *from, flagtype flags);
|
bool passable(cell *w, cell *from, flagtype flags);
|
||||||
|
|
||||||
@ -2430,3 +2431,6 @@ void clear_euland(eLand first);
|
|||||||
|
|
||||||
extern eMonster passive_switch;
|
extern eMonster passive_switch;
|
||||||
|
|
||||||
|
bool cannotPickupItem(cell *c, bool telekinesis);
|
||||||
|
bool canPickupItemWithMagnetism(cell *c, cell *from);
|
||||||
|
void pickupMovedItems(cell *c);
|
||||||
|
@ -329,6 +329,9 @@ namespace inv {
|
|||||||
for(auto& it: lateextraorbs) gainLate(it.treasure, it.orb);
|
for(auto& it: lateextraorbs) gainLate(it.treasure, it.orb);
|
||||||
|
|
||||||
gainOrbs(itGlowCrystal, itOrbSide2);
|
gainOrbs(itGlowCrystal, itOrbSide2);
|
||||||
|
gainOrbs(itSwitch, itOrbPhasing);
|
||||||
|
gainOrbs(itMagnet, itOrbMagnetism);
|
||||||
|
gainOrbs(itInvix, itOrbDestruction);
|
||||||
|
|
||||||
if(items[itOrbLove] && !items[itSavedPrincess]) items[itSavedPrincess] = 1;
|
if(items[itOrbLove] && !items[itSavedPrincess]) items[itSavedPrincess] = 1;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#define ORBLINES 66
|
#define ORBLINES 70
|
||||||
|
|
||||||
// orbgen flags
|
// orbgen flags
|
||||||
|
|
||||||
@ -111,6 +111,10 @@ const orbinfo orbinfos[ORBLINES] = {
|
|||||||
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbFish},
|
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbFish},
|
||||||
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDragon},
|
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDragon},
|
||||||
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDash},
|
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDash},
|
||||||
|
{orbgenflags::S_GUEST, laSwitch, 2000, 0, itOrbSpace},
|
||||||
|
{orbgenflags::S_NATIVE, laSwitch, 2000, 3000, itOrbPhasing},
|
||||||
|
{orbgenflags::S_NATIVE, laMagnetic, 2000, 3000, itOrbMagnetism},
|
||||||
|
{orbgenflags::S_NATIVE, laInvincible, 2000, 3000, itOrbDestruction},
|
||||||
{orbgenflags::S_NATIVE, laWhirlpool, 0, 2000, itOrbWater}, // needs to be last
|
{orbgenflags::S_NATIVE, laWhirlpool, 0, 2000, itOrbWater}, // needs to be last
|
||||||
};
|
};
|
||||||
|
|
||||||
|
46
orbs.cpp
46
orbs.cpp
@ -593,6 +593,11 @@ void jumpTo(cell *dest, eItem byWhat, int bonuskill = 0, eMonster dashmon = moNo
|
|||||||
addMessage(XLAT("You vault over %the1!", dashmon));
|
addMessage(XLAT("You vault over %the1!", dashmon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(byWhat == itOrbPhasing) {
|
||||||
|
useupOrb(itOrbPhasing, 5);
|
||||||
|
addMessage(XLAT("You jump!"));
|
||||||
|
}
|
||||||
|
|
||||||
mirror::destroyAll();
|
mirror::destroyAll();
|
||||||
|
|
||||||
for(int i=9; i>=0; i--)
|
for(int i=9; i>=0; i--)
|
||||||
@ -619,9 +624,16 @@ void growIvyTo(cell *dest, cell *src) {
|
|||||||
monstersTurn();
|
monstersTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair<int, bool> spacedrain(cell *c) {
|
||||||
|
int d = c->cpdist;
|
||||||
|
bool usemagnet = items[itOrbMagnetism] && d > 0;
|
||||||
|
if(usemagnet) d--;
|
||||||
|
return {d * d, usemagnet};
|
||||||
|
}
|
||||||
|
|
||||||
void telekinesis(cell *dest) {
|
void telekinesis(cell *dest) {
|
||||||
|
|
||||||
int cost = dest->cpdist * dest->cpdist;
|
auto cost = spacedrain(dest);
|
||||||
|
|
||||||
if(dest->land == laAlchemist && isAlchAny(dest) && isAlchAny(cwt.c))
|
if(dest->land == laAlchemist && isAlchAny(dest) && isAlchAny(cwt.c))
|
||||||
dest->wall = cwt.c->wall;
|
dest->wall = cwt.c->wall;
|
||||||
@ -642,9 +654,12 @@ void telekinesis(cell *dest) {
|
|||||||
|
|
||||||
moveItem(dest, cwt.c, true);
|
moveItem(dest, cwt.c, true);
|
||||||
collectItem(cwt.c, true);
|
collectItem(cwt.c, true);
|
||||||
useupOrb(itOrbSpace, cost);
|
useupOrb(itOrbSpace, cost.first);
|
||||||
|
if(cost.second)
|
||||||
|
markOrb(itOrbMagnetism);
|
||||||
|
|
||||||
createNoise(3);
|
createNoise(3);
|
||||||
|
checkSwitch();
|
||||||
bfs();
|
bfs();
|
||||||
if(!shmup::on) checkmoveO();
|
if(!shmup::on) checkmoveO();
|
||||||
}
|
}
|
||||||
@ -984,7 +999,7 @@ eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (0) telekinesis
|
// (0) telekinesis
|
||||||
if(c->item && !itemHiddenFromSight(c) && !cwt.c->item && items[itOrbSpace] >= fixpower(c->cpdist * c->cpdist) && !cantGetGrimoire(c, !isCheck(a))
|
if(c->item && !itemHiddenFromSight(c) && !cwt.c->item && items[itOrbSpace] >= fixpower(spacedrain(c).first) && !cantGetGrimoire(c, !isCheck(a))
|
||||||
&& c->item != itBarrow) {
|
&& c->item != itBarrow) {
|
||||||
if(!isCheck(a)) telekinesis(c);
|
if(!isCheck(a)) telekinesis(c);
|
||||||
return itOrbSpace;
|
return itOrbSpace;
|
||||||
@ -1091,6 +1106,31 @@ eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(items[itOrbPhasing] && c->cpdist == 2) {
|
||||||
|
jumpstate = 21;
|
||||||
|
int i = items[itOrbAether];
|
||||||
|
if(i) items[itOrbAether] = i-1;
|
||||||
|
for(int i=0; i<cwt.c->type; i++) {
|
||||||
|
cell *c2 = cwt.c->mov[i];
|
||||||
|
if(isNeighbor(c2, c) && !nonAdjacent(cwt.c, c2) && !nonAdjacent(c2, c)) {
|
||||||
|
jumpthru = c2;
|
||||||
|
if(passable(c, cwt.c, P_ISPLAYER | P_PHASE)) {
|
||||||
|
jumpstate = 22;
|
||||||
|
if(c2->monst || isWall(c2)) {
|
||||||
|
jumpstate = 23;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items[itOrbAether] = i;
|
||||||
|
if(jumpstate == 23 && !monstersnearO(a, c, NULL, moPlayer, NULL, cwt.c)) {
|
||||||
|
jumpstate = 24;
|
||||||
|
if(!isCheck(a)) jumpTo(c, itOrbPhasing);
|
||||||
|
return itOrbPhasing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// (1) switch with an illusion
|
// (1) switch with an illusion
|
||||||
if(items[itOrbTeleport] && c->monst == moIllusion && !cwt.c->monst && teleportAction() == 1) {
|
if(items[itOrbTeleport] && c->monst == moIllusion && !cwt.c->monst && teleportAction() == 1) {
|
||||||
if(!isCheck(a)) teleportTo(c);
|
if(!isCheck(a)) teleportTo(c);
|
||||||
|
Loading…
Reference in New Issue
Block a user