Orb of Magnetism. Orb of Phasing. Also fixed Aether in Whirlpool.

This commit is contained in:
Zeno Rogue 2017-12-30 23:47:10 +01:00
parent 3d4e7f501a
commit 9d1fe00d8f
9 changed files with 108 additions and 14 deletions

View File

@ -1211,6 +1211,9 @@ itemtype iinf[ittypes] = {
{ '*', 0x80FF80, "Invix Treasure", NODESCYET},
{ '*', 0x80FF80, "Monopole", NODESCYET},
{ '*', 0xFFFF80, "Junk", NODESCYET},
{ 'o', 0x80FF80, "Orb of Phasing", NODESCYET},
{ 'o', 0xFFFF80, "Orb of Magnetism", NODESCYET},
{ 'o', 0xFFFF80, "Orb of Destruction", NODESCYET},
};
// --- wall types ---

View File

@ -70,7 +70,7 @@ struct genderswitch_t {
#define NUM_GS 6
static const int ittypes = 127;
static const int ittypes = 130;
struct itemtype {
char glyph;
@ -115,7 +115,8 @@ enum eItem {
itLavaLily, itHunting, itBlizzard, itTerra,
itOrbSide1, itOrbSide2, itOrbSide3,
itOrbLava, itOrbMorph, itGlowCrystal, itSnake,
itDock, itInvix, itMagnet, itSwitch
itDock, itInvix, itMagnet, itSwitch,
itOrbPhasing, itOrbMagnetism, itOrbDestruction
};
static const int walltypes = 107;

View File

@ -139,8 +139,7 @@ namespace whirlwind {
animateMovement(whirlline[i+1], whirlline[i], LAYER_BOAT);
}
for(int i=0; i<z; i++)
if(isPlayerOn(whirlline[i]) && whirlline[i]->item)
collectItem(whirlline[i], true);
pickupMovedItems(whirlline[i]);
}
void move() {
@ -985,6 +984,8 @@ namespace whirlpool {
if(wfrom->item == itKey || wfrom->item == itOrbYendor)
for(int i=0; i<wto->type; i++) createMov(wto, i);
moveItem(wfrom, wto, false);
pickupMovedItems(wfrom);
pickupMovedItems(wto);
}
if(wto && !wfrom)
@ -2184,7 +2185,7 @@ void livecaves() {
}
if(c->aitmp < 0 && c->wall == waBoat) c->wall = waStrandedBoat;
if(c->aitmp < 0 && c->wall == waSea) c->wall = waNone;
}
}
}
for(int i=0; i<size(bringlife); i++) {

View File

@ -548,7 +548,7 @@ bool haveRangedOrb() {
items[itOrbFrog] || items[itOrbSummon] || items[itOrbMatter] ||
items[itRevolver] || items[itOrbStunning] || items[itStrongWind] ||
items[itOrbDomination] || items[itOrbNature] || items[itOrbDash] ||
items[itOrbMorph];
items[itOrbMorph] || items[itOrbPhasing];
}
bool isOffensiveOrb(eItem it) {

View File

@ -1127,6 +1127,9 @@ int monstersnear(stalemate1& sm) {
dynamicval<eMonster> sw(passive_switch, passive_switch);
if(sm.moveto->item && itemclass(sm.moveto->item) == IC_TREASURE)
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;
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."));
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) {
@ -6292,12 +6305,33 @@ int ambush(cell *c, eItem what) {
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) {
int pg = gold();
bool dopickup = true;
if(itemHidden(c2) && !telekinesis && !(isWatery(c2) && markOrb(itOrbFish)))
if(cannotPickupItem(c2, telekinesis))
return false;
/* if(c2->item == itHolyGrail && telekinesis)
@ -6823,8 +6857,12 @@ void terracotta() {
eMonster passive_switch;
void monstersTurn() {
void checkSwitch() {
passive_switch = (gold() & 1) ? moSwitch1 : moSwitch2;
}
void monstersTurn() {
checkSwitch();
mirror::breakAll();
DEBT("bfs");
bfs();
@ -7099,7 +7137,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
}
if(againstCurrent(c2, cwt.c) && !markOrb(itOrbWater)) {
if(markOrb(itOrbFish)) goto escape;
if(markOrb(itOrbFish) || markOrb(itOrbAether)) goto escape;
if(!checkonly)
addMessage(XLAT("You cannot go against the current!"));
return false;

View File

@ -823,6 +823,7 @@ void setGLProjection();
#define P_CLIMBDOWN Flag(30) // allow climbing down
#define P_REPTILE Flag(31) // is reptile
#define P_VOID Flag(32) // void beast
#define P_PHASE Flag(33) // phasing movement
bool passable(cell *w, cell *from, flagtype flags);
@ -2430,3 +2431,6 @@ void clear_euland(eLand first);
extern eMonster passive_switch;
bool cannotPickupItem(cell *c, bool telekinesis);
bool canPickupItemWithMagnetism(cell *c, cell *from);
void pickupMovedItems(cell *c);

View File

@ -329,6 +329,9 @@ namespace inv {
for(auto& it: lateextraorbs) gainLate(it.treasure, it.orb);
gainOrbs(itGlowCrystal, itOrbSide2);
gainOrbs(itSwitch, itOrbPhasing);
gainOrbs(itMagnet, itOrbMagnetism);
gainOrbs(itInvix, itOrbDestruction);
if(items[itOrbLove] && !items[itSavedPrincess]) items[itSavedPrincess] = 1;

View File

@ -1,4 +1,4 @@
#define ORBLINES 66
#define ORBLINES 70
// orbgen flags
@ -111,6 +111,10 @@ const orbinfo orbinfos[ORBLINES] = {
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbFish},
{orbgenflags::S_GUEST, laDocks, 3000, 0, itOrbDragon},
{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
};

View File

@ -593,6 +593,11 @@ void jumpTo(cell *dest, eItem byWhat, int bonuskill = 0, eMonster dashmon = moNo
addMessage(XLAT("You vault over %the1!", dashmon));
}
if(byWhat == itOrbPhasing) {
useupOrb(itOrbPhasing, 5);
addMessage(XLAT("You jump!"));
}
mirror::destroyAll();
for(int i=9; i>=0; i--)
@ -619,9 +624,16 @@ void growIvyTo(cell *dest, cell *src) {
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) {
int cost = dest->cpdist * dest->cpdist;
auto cost = spacedrain(dest);
if(dest->land == laAlchemist && isAlchAny(dest) && isAlchAny(cwt.c))
dest->wall = cwt.c->wall;
@ -642,9 +654,12 @@ void telekinesis(cell *dest) {
moveItem(dest, cwt.c, true);
collectItem(cwt.c, true);
useupOrb(itOrbSpace, cost);
useupOrb(itOrbSpace, cost.first);
if(cost.second)
markOrb(itOrbMagnetism);
createNoise(3);
checkSwitch();
bfs();
if(!shmup::on) checkmoveO();
}
@ -984,7 +999,7 @@ eItem targetRangedOrb(cell *c, orbAction a) {
}
// (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) {
if(!isCheck(a)) telekinesis(c);
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
if(items[itOrbTeleport] && c->monst == moIllusion && !cwt.c->monst && teleportAction() == 1) {
if(!isCheck(a)) teleportTo(c);