mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-26 17:06:59 +00:00
fixed Orbs in undo
This commit is contained in:
parent
a36fb633b2
commit
2636b195a2
10
items.cpp
10
items.cpp
@ -128,10 +128,20 @@ EX bool collectItem(cell *c2, bool telekinesis IS(false)) {
|
|||||||
#if CAP_TOUR
|
#if CAP_TOUR
|
||||||
else if(tour::on && (c2->item == itOrbSafety || c2->item == itOrbRecall)) {
|
else if(tour::on && (c2->item == itOrbSafety || c2->item == itOrbRecall)) {
|
||||||
addMessage(XLAT("This Orb is not compatible with the Tutorial."));
|
addMessage(XLAT("This Orb is not compatible with the Tutorial."));
|
||||||
|
if(changes.on) changes.rollback();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if(c2->item == itOrbSafety) {
|
else if(c2->item == itOrbSafety) {
|
||||||
|
|
||||||
|
if(changes.on) {
|
||||||
|
if(changes.checking) {
|
||||||
|
changes.rollback();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
changes.commit();
|
||||||
|
}
|
||||||
|
|
||||||
playSound(c2, "pickup-orb"); // TODO safety
|
playSound(c2, "pickup-orb"); // TODO safety
|
||||||
if(!dual::state) items[c2->item] = 7;
|
if(!dual::state) items[c2->item] = 7;
|
||||||
if(shmup::on)
|
if(shmup::on)
|
||||||
|
57
orbs.cpp
57
orbs.cpp
@ -593,6 +593,9 @@ void teleportTo(cell *dest) {
|
|||||||
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {
|
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {
|
||||||
if(byWhat != itStrongWind) playSound(dest, "orb-frog");
|
if(byWhat != itStrongWind) playSound(dest, "orb-frog");
|
||||||
cell *from = cwt.at;
|
cell *from = cwt.at;
|
||||||
|
changes.value_keep(cwt);
|
||||||
|
changes.ccell(dest);
|
||||||
|
changes.ccell(cwt.at);
|
||||||
|
|
||||||
if(byWhat == itOrbFrog) {
|
if(byWhat == itOrbFrog) {
|
||||||
useupOrb(itOrbFrog, 5);
|
useupOrb(itOrbFrog, 5);
|
||||||
@ -615,14 +618,34 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons
|
|||||||
|
|
||||||
cell *c1 = cwt.at;
|
cell *c1 = cwt.at;
|
||||||
animateMovement(match(cwt.at, dest), LAYER_SMALL);
|
animateMovement(match(cwt.at, dest), LAYER_SMALL);
|
||||||
current_display->which_copy = ggmatrix(dest);
|
|
||||||
cwt.at = dest;
|
cwt.at = dest;
|
||||||
forCellIdEx(c2, i, dest) if(c2->cpdist < dest->cpdist) {
|
forCellIdEx(c2, i, dest) if(c2->cpdist < dest->cpdist) {
|
||||||
cwt.spin = i;
|
cwt.spin = i;
|
||||||
flipplayer = true;
|
flipplayer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!monstersnearO(a, dest, moPlayer, NULL, cwt.at)) {
|
sword::reset();
|
||||||
|
stabbingAttack(c1, dest, moPlayer, bonuskill);
|
||||||
|
playerMoveEffects(c1, dest);
|
||||||
|
|
||||||
|
if(itemclass(byWhat) == IC_ORB)
|
||||||
|
apply_impact(dest);
|
||||||
|
|
||||||
|
// do not apply movecost later, when from no longer exists
|
||||||
|
if(cwt.at->item == itOrbSafety) {
|
||||||
|
movecost(from, dest, 2);
|
||||||
|
from = NULL;
|
||||||
|
}
|
||||||
|
if(cwt.at->item != itOrbYendor && cwt.at->item != itHolyGrail) {
|
||||||
|
auto c = collectItem(cwt.at, true);
|
||||||
|
if(c) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mirror::destroyAll();
|
||||||
|
|
||||||
|
if(monstersnearO(a, dest, moPlayer, NULL, cwt.at)) {
|
||||||
changes.rollback();
|
changes.rollback();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -632,30 +655,16 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changes.commit();
|
||||||
|
|
||||||
|
current_display->which_copy = ggmatrix(dest);
|
||||||
countLocalTreasure();
|
countLocalTreasure();
|
||||||
|
|
||||||
sword::reset();
|
|
||||||
stabbingAttack(c1, dest, moPlayer, bonuskill);
|
|
||||||
playerMoveEffects(c1, dest);
|
|
||||||
|
|
||||||
// do not apply movecost later, when from no longer exists
|
|
||||||
if(cwt.at->item == itOrbSafety) {
|
|
||||||
movecost(from, dest, 2);
|
|
||||||
from = NULL;
|
|
||||||
}
|
|
||||||
if(cwt.at->item != itOrbYendor && cwt.at->item != itHolyGrail)
|
|
||||||
collectItem(cwt.at, true);
|
|
||||||
|
|
||||||
mirror::destroyAll();
|
|
||||||
|
|
||||||
for(int i=9; i>=0; i--)
|
for(int i=9; i>=0; i--)
|
||||||
setdist(cwt.at, i, NULL);
|
setdist(cwt.at, i, NULL);
|
||||||
|
|
||||||
if(from) movecost(from, dest, 2);
|
if(from) movecost(from, dest, 2);
|
||||||
|
|
||||||
if(itemclass(byWhat) == IC_ORB)
|
|
||||||
apply_impact(dest);
|
|
||||||
|
|
||||||
createNoise(1);
|
createNoise(1);
|
||||||
|
|
||||||
if(shmup::on)
|
if(shmup::on)
|
||||||
@ -1159,7 +1168,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
|
|
||||||
// (0-) strong wind
|
// (0-) strong wind
|
||||||
if(items[itStrongWind] && c->cpdist == 2 && cwt.at == whirlwind::jumpFromWhereTo(c, true)) {
|
if(items[itStrongWind] && c->cpdist == 2 && cwt.at == whirlwind::jumpFromWhereTo(c, true)) {
|
||||||
changes.init();
|
changes.init(isCheck(a));
|
||||||
if(jumpTo(a, c, itStrongWind)) return itStrongWind;
|
if(jumpTo(a, c, itStrongWind)) return itStrongWind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1233,7 +1242,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
items[itOrbAether] = i;
|
items[itOrbAether] = i;
|
||||||
|
|
||||||
if(jumpstate == 15) {
|
if(jumpstate == 15) {
|
||||||
changes.init();
|
changes.init(isCheck(a));
|
||||||
int k = tkills();
|
int k = tkills();
|
||||||
eMonster m = jumpthru->monst;
|
eMonster m = jumpthru->monst;
|
||||||
if(jumpthru->wall == waShrub) {
|
if(jumpthru->wall == waShrub) {
|
||||||
@ -1254,7 +1263,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
jumpstate = check_jump(cwt.at, c, P_ISPLAYER, jumpthru);
|
jumpstate = check_jump(cwt.at, c, P_ISPLAYER, jumpthru);
|
||||||
items[itOrbAether] = i;
|
items[itOrbAether] = i;
|
||||||
if(jumpstate == 3) {
|
if(jumpstate == 3) {
|
||||||
changes.init();
|
changes.init(isCheck(a));
|
||||||
if(jumpTo(a, c, itOrbFrog)) jumpstate = 4;
|
if(jumpTo(a, c, itOrbFrog)) jumpstate = 4;
|
||||||
if(jumpstate == 4) return itOrbFrog;
|
if(jumpstate == 4) return itOrbFrog;
|
||||||
}
|
}
|
||||||
@ -1267,7 +1276,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
jumpstate = 20 + check_phase(cwt.at, c, P_ISPLAYER, jumpthru);
|
jumpstate = 20 + check_phase(cwt.at, c, P_ISPLAYER, jumpthru);
|
||||||
items[itOrbAether] = i;
|
items[itOrbAether] = i;
|
||||||
if(jumpstate == 23) {
|
if(jumpstate == 23) {
|
||||||
changes.init();
|
changes.init(isCheck(a));
|
||||||
if(jumpTo(a, c, itOrbPhasing)) jumpstate = 24;
|
if(jumpTo(a, c, itOrbPhasing)) jumpstate = 24;
|
||||||
}
|
}
|
||||||
if(shmup::on) shmup::popmonsters();
|
if(shmup::on) shmup::popmonsters();
|
||||||
@ -1309,7 +1318,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||||||
bool inrange = false;
|
bool inrange = false;
|
||||||
for(cell *c1: gun_targets(cwt.at)) if(c1 == c) inrange = true;
|
for(cell *c1: gun_targets(cwt.at)) if(c1 == c) inrange = true;
|
||||||
if(inrange) {
|
if(inrange) {
|
||||||
changes.init();
|
changes.init(isCheck(a));
|
||||||
gun_attack(c), apply_impact(c);
|
gun_attack(c), apply_impact(c);
|
||||||
if(monstersnearO(a, cwt.at, moPlayer, NULL, cwt.at)) {
|
if(monstersnearO(a, cwt.at, moPlayer, NULL, cwt.at)) {
|
||||||
changes.rollback();
|
changes.rollback();
|
||||||
|
105
pcmove.cpp
105
pcmove.cpp
@ -265,7 +265,7 @@ bool pcmove::movepcto() {
|
|||||||
fmsAttack = forcedmovetype == fmSkip || forcedmovetype == fmAttack;
|
fmsAttack = forcedmovetype == fmSkip || forcedmovetype == fmAttack;
|
||||||
fmsActivate = forcedmovetype == fmSkip || forcedmovetype == fmActivate;
|
fmsActivate = forcedmovetype == fmSkip || forcedmovetype == fmActivate;
|
||||||
|
|
||||||
changes.init();
|
changes.init(checkonly);
|
||||||
bool b = (d >= 0) ? actual_move() : stay();
|
bool b = (d >= 0) ? actual_move() : stay();
|
||||||
if(checkonly || !b) {
|
if(checkonly || !b) {
|
||||||
changes.rollback();
|
changes.rollback();
|
||||||
@ -274,6 +274,44 @@ bool pcmove::movepcto() {
|
|||||||
println(hlog, "error: not commited!");
|
println(hlog, "error: not commited!");
|
||||||
changes.commit();
|
changes.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!b) {
|
||||||
|
// bool try_instant = (forcedmovetype == fmInstant) || (forcedmovetype == fmSkip && !passable(c2, cwt.at, P_ISPLAYER | P_MIRROR | P_USEBOAT | P_FRIENDSWAP));
|
||||||
|
|
||||||
|
if(items[itOrbFlash]) {
|
||||||
|
if(checkonly) { nextmovetype = lmInstant; return true; }
|
||||||
|
if(orbProtection(itOrbFlash)) return true;
|
||||||
|
activateFlash();
|
||||||
|
checkmove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(items[itOrbLightning]) {
|
||||||
|
if(checkonly) { nextmovetype = lmInstant; return true; }
|
||||||
|
if(orbProtection(itOrbLightning)) return true;
|
||||||
|
activateLightning();
|
||||||
|
checkmove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(false && who_kills_me == moOutlaw && items[itRevolver]) {
|
||||||
|
cell *c2 = cwt.cpeek();
|
||||||
|
for(int i=0; i<c2->type; i++) {
|
||||||
|
cell *c3 = c2->move(i);
|
||||||
|
if(c3) for(int i=0; i<c3->type; i++) {
|
||||||
|
cell *c4 = c3->move(i);
|
||||||
|
if(c4 && c4->monst == moOutlaw) {
|
||||||
|
eItem i = targetRangedOrb(c4, roCheck);
|
||||||
|
if(i == itRevolver) {
|
||||||
|
targetRangedOrb(c4, roKeyboard);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,6 +378,7 @@ bool pcmove::swing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool pcmove::after_instant(bool kl) {
|
bool pcmove::after_instant(bool kl) {
|
||||||
|
changes.commit();
|
||||||
keepLightning = kl;
|
keepLightning = kl;
|
||||||
bfs();
|
bfs();
|
||||||
keepLightning = false;
|
keepLightning = false;
|
||||||
@ -370,12 +409,14 @@ struct changes_t {
|
|||||||
vector<reaction_t> rollbacks;
|
vector<reaction_t> rollbacks;
|
||||||
vector<reaction_t> commits;
|
vector<reaction_t> commits;
|
||||||
bool on;
|
bool on;
|
||||||
|
bool checking;
|
||||||
|
|
||||||
void init() {
|
void init(bool ch) {
|
||||||
on = true;
|
on = true;
|
||||||
for(cell *dc: dcal) ccell(dc);
|
for(cell *dc: dcal) ccell(dc);
|
||||||
value_keep(kills);
|
value_keep(kills);
|
||||||
value_keep(items);
|
value_keep(items);
|
||||||
|
checking = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void commit() {
|
void commit() {
|
||||||
@ -498,8 +539,6 @@ bool pcmove::actual_move() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool try_instant = (forcedmovetype == fmInstant) || (forcedmovetype == fmSkip && !passable(c2, cwt.at, P_ISPLAYER | P_MIRROR | P_USEBOAT | P_FRIENDSWAP));
|
|
||||||
|
|
||||||
if(items[itOrbDomination] > ORBBASE && isMountable(c2->monst) && !monstersnear2() && fmsMove) {
|
if(items[itOrbDomination] > ORBBASE && isMountable(c2->monst) && !monstersnear2() && fmsMove) {
|
||||||
if(checkonly) { nextmovetype = lmMove; return true; }
|
if(checkonly) { nextmovetype = lmMove; return true; }
|
||||||
if(!isMountable(cwt.at->monst)) dragon::target = NULL;
|
if(!isMountable(cwt.at->monst)) dragon::target = NULL;
|
||||||
@ -511,20 +550,6 @@ bool pcmove::actual_move() {
|
|||||||
return perform_move_or_jump();
|
return perform_move_or_jump();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items[itOrbFlash] && try_instant) {
|
|
||||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
|
||||||
if(orbProtection(itOrbFlash)) return true;
|
|
||||||
activateFlash();
|
|
||||||
return after_instant(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(items[itOrbLightning] && try_instant) {
|
|
||||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
|
||||||
if(orbProtection(itOrbLightning)) return true;
|
|
||||||
activateLightning();
|
|
||||||
return after_instant(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isActivable(c2) && fmsActivate) {
|
if(isActivable(c2) && fmsActivate) {
|
||||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
if(checkonly) { nextmovetype = lmInstant; return true; }
|
||||||
activateActiv(c2, true);
|
activateActiv(c2, true);
|
||||||
@ -782,6 +807,9 @@ bool pcmove::attack() {
|
|||||||
auto& c2 = mi.t;
|
auto& c2 = mi.t;
|
||||||
if(!fmsAttack) return false;
|
if(!fmsAttack) return false;
|
||||||
|
|
||||||
|
if(items[itOrbFlash] || items[itOrbLightning])
|
||||||
|
return false;
|
||||||
|
|
||||||
attackflags = AF_NORMAL;
|
attackflags = AF_NORMAL;
|
||||||
if(items[itOrbSpeed]&1) attackflags |= AF_FAST;
|
if(items[itOrbSpeed]&1) attackflags |= AF_FAST;
|
||||||
if(items[itOrbSlaying]) attackflags |= AF_CRUSH;
|
if(items[itOrbSlaying]) attackflags |= AF_CRUSH;
|
||||||
@ -925,8 +953,10 @@ bool pcmove::perform_actual_move() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(items[itOrbWinter])
|
if(items[itOrbWinter])
|
||||||
forCellEx(c3, c2) if(c3->wall == waIcewall && c3->item)
|
forCellEx(c3, c2) if(c3->wall == waIcewall && c3->item) {
|
||||||
markOrb(itOrbWinter), collectItem(c3);
|
markOrb(itOrbWinter);
|
||||||
|
if(collectItem(c3)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
movecost(cwt.at, c2, 2);
|
movecost(cwt.at, c2, 2);
|
||||||
|
|
||||||
@ -976,41 +1006,6 @@ bool pcmove::perform_move_or_jump() {
|
|||||||
|
|
||||||
if(monstersnear(cwt.at, moPlayer, nullptr, c1)) {
|
if(monstersnear(cwt.at, moPlayer, nullptr, c1)) {
|
||||||
changes.rollback();
|
changes.rollback();
|
||||||
|
|
||||||
/* todo
|
|
||||||
if(items[itOrbFlash]) {
|
|
||||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
|
||||||
if(orbProtection(itOrbFlash)) return true;
|
|
||||||
activateFlash();
|
|
||||||
checkmove();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(items[itOrbLightning]) {
|
|
||||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
|
||||||
if(orbProtection(itOrbLightning)) return true;
|
|
||||||
activateLightning();
|
|
||||||
checkmove();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(who_kills_me == moOutlaw && items[itRevolver]) {
|
|
||||||
for(int i=0; i<c2->type; i++) {
|
|
||||||
cell *c3 = c2->move(i);
|
|
||||||
if(c3) for(int i=0; i<c3->type; i++) {
|
|
||||||
cell *c4 = c3->move(i);
|
|
||||||
if(c4 && c4->monst == moOutlaw) {
|
|
||||||
eItem i = targetRangedOrb(c4, roCheck);
|
|
||||||
if(i == itRevolver) {
|
|
||||||
targetRangedOrb(c4, roKeyboard);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(errormsgs && !checkonly) wouldkill("%The1 would kill you there!");
|
if(errormsgs && !checkonly) wouldkill("%The1 would kill you there!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user