1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-26 01:50:36 +00:00
This commit is contained in:
Zeno Rogue 2021-07-10 22:05:38 +02:00
commit 017a4750ed
14 changed files with 213 additions and 52 deletions

View File

@ -567,7 +567,8 @@ EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) {
forCellEx(c1, c) {
changes.ccell(c1);
c1->item = itNone;
if(c1->wall == waDeadwall || c1->wall == waDeadfloor2) c1->wall = waCavewall;
if(c1->wall == waDeadwall) c1->wall = waCavewall;
if(c1->wall == waDeadfloor2 && !c1->monst && !isPlayerOn(c1)) c1->wall = waCavewall;
if(c1->wall == waDeadfloor) c1->wall = waCavefloor;
}
}
@ -1050,6 +1051,7 @@ EX void killFriendlyIvy() {
EX bool monsterPushable(cell *c2) {
if(markOrb(itCurseWeakness) && (c2->stuntime < 2 || attackJustStuns(c2, 0, moPlayer))) return false;
if(isMultitile(c2->monst)) return false;
return (c2->monst != moFatGuard && !(isMetalBeast(c2->monst) && c2->stuntime < 2) && c2->monst != moTortoise && c2->monst != moTerraWarrior && c2->monst != moVizier && c2->monst != moWorldTurtle);
}

View File

@ -2300,7 +2300,7 @@ void celldrawer::draw_item_full() {
color_t icol = 0;
if(specialland == laMotion && items[itOrbInvis] && c->wall == waChasm) {
if(ls::single() && specialland == laMotion && items[itOrbInvis] && c->wall == waChasm) {
if(c->mondir < c->type) {
vid.linewidth *= 3;
queueline(V*C0, V*currentmap->adj(c, c->mondir) * C0, 0xFFD500FF, 4);

View File

@ -105,6 +105,7 @@ EX bool monstersnear(cell *c, eMonster who) {
int res = 0;
bool fast = false;
bool kraken_will_destroy_boat = false;
elec::builder b;
if(elec::affected(c)) { who_kills_me = moLightningBolt; res++; }
@ -119,7 +120,7 @@ EX bool monstersnear(cell *c, eMonster who) {
if(who == moPlayer || items[itOrbEmpathy]) {
fast = (items[itOrbSpeed] && (items[itOrbSpeed] & 1));
if(who == moPlayer && c->item == itOrbSpeed && !items[itOrbSpeed]) fast = true;
if(who == moPlayer && !isPlayerOn(c) && c->item == itOrbSpeed && !items[itOrbSpeed]) fast = true;
}
if(havewhat&HF_OUTLAW) {
@ -167,10 +168,9 @@ EX bool monstersnear(cell *c, eMonster who) {
if(elec::affected(c2)) continue;
if(fast && c2->monst != moWitchSpeed) continue;
// Krakens just destroy boats
if(c2->monst == moKrakenT && c->wall == waBoat) {
if(krakensafe(c)) continue;
else if(warningprotection(XLAT("This move appears dangerous -- are you sure?")) && res == 0) m = moWarning;
else continue;
if(who == moPlayer && c2->monst == moKrakenT && c->wall == waBoat) {
kraken_will_destroy_boat = true;
continue;
}
// they cannot attack through vines
if(!canAttack(c2, c2->monst, c, who, AF_NEXTTURN)) continue;
@ -183,11 +183,15 @@ EX bool monstersnear(cell *c, eMonster who) {
}
}
if(who == moPlayer && res && (markOrb2(itOrbShield) || markOrb2(itOrbShell)) && !eaten)
res = 0;
if(who == moPlayer && res && markOrb2(itOrbDomination) && c->monst)
res = 0;
if(kraken_will_destroy_boat && !krakensafe(c) && warningprotection(XLAT("This move appears dangerous -- are you sure?"))) {
if (res == 0) who_kills_me = moWarning;
res++;
} else {
if(who == moPlayer && res && (markOrb2(itOrbShield) || markOrb2(itOrbShell)) && !eaten)
res = 0;
if(who == moPlayer && res && markOrb2(itOrbDomination) && c->monst)
res = 0;
}
return !!res;
}

View File

@ -367,8 +367,8 @@ int arg::readCommon() {
printf(" -offline - don't connect to Steam (for Steam versions)\n");
printf(" -I ITEM n - start with n of ITEM (activates cheat and disables ghosts)\n");
printf(" -fix - fix the seed\n");
printf("Toggles: -o0 disables, -o1 enables, -o switches");
printf("Not all options are documented, see hyper.cpp");
printf("Toggles: -o0 disables, -o1 enables, -o switches\n");
printf("Not all options are documented, see hyper.cpp\n");
exit(0);
}
else return 1;

View File

@ -2349,7 +2349,7 @@ EX void livecaves() {
for(cell *c2: adj_minefield_cells(c)) {
eWall w = c2->wall;
if(w == waDeadfloor) hv++, bringlife.push_back(c2);
else if(w == waDeadwall || (w == waDeadfloor2 && !c2->monst))
else if(w == waDeadwall || (w == waDeadfloor2 && !c2->monst && !isPlayerOn(c2)))
hv--, bringlife.push_back(c2);
else if(w == waCavefloor) hv++;
else if(w == waCavewall) hv--;
@ -2597,7 +2597,7 @@ EX }
EX namespace dragon {
EX int whichturn; // which turn has the target been set on
EX cell *target; // actually for all Orb of Control
EX cell *target; // actually for all Orb of Domination
void pullback(cell *c) {
int maxlen = iteration_limit;
@ -2977,6 +2977,7 @@ EX namespace kraken {
for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i];
if(c->monst == moKrakenT && !c->stuntime) forCellEx(c2, c) {
if (!logical_adjacent(c2,moKrakenT,c)) continue;
bool dboat = false;
if(c2->monst && canAttack(c, moKrakenT, c2, c2->monst, AF_ONLY_FBUG)) {
attackMonster(c2, AF_NORMAL | AF_MSG, c->monst);
@ -3467,6 +3468,7 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () {
clearing::score.clear();
tortoise::emap.clear();
tortoise::babymap.clear();
dragon::target = NULL;
#if CAP_FIELD
prairie::lasttreasure = NULL;
prairie::enter = NULL;
@ -3510,6 +3512,7 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () {
}
return false;
});
set_if_removed(dragon::target, NULL);
#if CAP_FIELD
set_if_removed(prairie::lasttreasure, NULL);
set_if_removed(prairie::enter, NULL);

View File

@ -320,7 +320,7 @@ array<feature, 21> features {{
if(buildIvy(c, 0, c->type) && !peace::on) c->item = itVarTreasure;
}},
{0x000A08, 0, moNone, VF { if(c->wall == waNone && !c->monst && hrand(5000) < 100) c->wall = waSmallTree; }},
{0x100A10, 1, moRagingBull, VF { if(c->wall == waNone && hrand(10000) < 10 + items[itVarTreasure]) c->monst = moSleepBull, c->hitpoints = 3; }},
{0x100A10, 1, moRagingBull, VF { if(c->wall == waNone && !c->monst && hrand(10000) < 10 + items[itVarTreasure]) c->monst = moSleepBull, c->hitpoints = 3; }},
{0x00110C, 0, moNone, VF { if(c->wall == waNone && !c->monst && hrand(5000) < 100) c->wall = waBigTree; }},
{0x000A28, 1, moNone, VF { if(hrand(500) < 10) build_pool(c, false); } },
{0x100A00, 2, moVariantWarrior, VF { if(c->wall == waNone && !c->monst && hrand_var(40000)) c->monst = moVariantWarrior; }},
@ -458,7 +458,7 @@ EX void knightFlavorMessage(cell *c2) {
else if(cryst)
s = crystal::get_table_boundary();
#endif
else if(!quotient)
else if(!quotient && rad)
s = expansion.get_descendants(rad).get_str(100);
if(s == "") { msgid++; goto retry; }
addMessage(XLAT("\"Our Table seats %1 Knights!\"", s));
@ -470,7 +470,7 @@ EX void knightFlavorMessage(cell *c2) {
else if(cryst)
s = crystal::get_table_volume();
#endif
else if(!quotient)
else if(!quotient && rad)
s = expansion.get_descendants(rad-1, expansion.diskid).get_str(100);
if(s == "") { msgid++; goto retry; }
addMessage(XLAT("\"There are %1 floor tiles inside our Table!\"", s));

View File

@ -125,7 +125,7 @@ MONSTER( 'D', 0xFF0000, "Greater Demon", moGreater, CF_FACE_UP | CF_DEMON | CF_S
MONSTER( 'D', 0x800000, "Greater Demon", moGreaterM, CF_FACE_UP | CF_DEMON | CF_INACTIVE | CF_SPAM, RESERVED, moLesser, gdemonhelp)
MONSTER( 'd', 0xFF2020, "Lesser Demon", moLesser, CF_FACE_UP | CF_DEMON | CF_SLOWMOVER | CF_SPAM, RESERVED, moYeti, ldemonhelp)
MONSTER( 'd', 0x802020, "Lesser Demon", moLesserM, CF_FACE_UP | CF_DEMON | CF_INACTIVE | CF_SPAM, RESERVED, moLesser, ldemonhelp)
MONSTER( 'S', 0x2070C0, "Ice Shark", moShark, CF_FACE_SIDE | CF_SHARK, RESERVED, moShark,
MONSTER( 'S', 0x2070C0, "Ice Shark", moShark, CF_FACE_SIDE | CF_NOBLOW | CF_SHARK, RESERVED, moShark,
"This dangerous predator has killed many people, and has been sent to Cocytus."
)
MONSTER( 'W', 0xFFFFFF, "Running Dog", moRunDog, CF_FACE_SIDE, RESERVED, moYeti,
@ -221,7 +221,7 @@ MONSTER( '@', 0x8B4513, "Illusion", moIllusion, CF_FACE_SIDE | CF_NOGHOST | CF_N
)
MONSTER( 'P', 0xD00000, "Pirate", moPirate, CF_FACE_UP | CF_LEADER, RESERVED, moPirate,
"Just a typical hyperbolic pirate." )
MONSTER( 'S', 0x8080C0, "Shark", moCShark, CF_FACE_SIDE | CF_SHARK, RESERVED, moShark, "Just a nasty shark.")
MONSTER( 'S', 0x8080C0, "Shark", moCShark, CF_FACE_SIDE | CF_NOBLOW | CF_SHARK, RESERVED, moShark, "Just a nasty shark.")
MONSTER( 'P', 0x0000FF, "Parrot", moParrot, CF_FACE_SIDE | CF_NOBLOW | CF_SLIME | CF_IGNORE_SMELL, RESERVED, moSlime, "Parrots feel safe in the forests of Caribbean, so they "
"never leave them. But they will help the Pirates by attacking the intruders.")
MONSTER( 'S', 0xE09000, "Rock Snake", moHexSnake, ZERO | CF_NOGHOST | CF_NOBLOW | CF_MOUNTABLE | CF_IGNORE_SMELL | CF_MULTITILE | CF_WORM | CF_HIGH_THREAT, RESERVED, moNone, redsnakedes )
@ -329,7 +329,7 @@ MONSTER( 'D', 0xF09090, "Draugr", moDraugr, CF_FACE_UP | CF_NONLIVING | CF_SLOWM
"Animated corpses of ancient Viking warriors. They are immune to mundane weapons, "
"but they can be destroyed by your Orb of the Sword."
)
MONSTER( 'C', 0xC08000, "Friendly Ivy", moFriendlyIvy, ZERO | CF_NOGHOST | CF_NOBLOW | CF_FRIENDLY | CF_FACING | CF_ANYIVY, RESERVED, moNone, naturedesc )
MONSTER( 'C', 0xC08000, "Friendly Ivy", moFriendlyIvy, ZERO | CF_NOGHOST | CF_NOBLOW | CF_MULTITILE | CF_FRIENDLY | CF_FACING | CF_ANYIVY, RESERVED, moNone, naturedesc )
MONSTER( 'V', 0xC000C0, "Vampire Bat", moVampire, CF_FACE_SIDE | CF_BIRD | CF_FLYING | CF_UNARMED | CF_IGNORE_PLATE, RESERVED, moEagle,
"Vampire Bats don't attack normally, but they drain your magical powers if "
"they are at distance at most 2 from you."
@ -1562,7 +1562,7 @@ WALL( '=', 0x00C0C0, "shallow water", waShallow, ZERO, RESERVED, 0, sgWater,
)
WALL( '=', 0x0000A0, "deep water", waDeepWater, WF_WATER, RESERVED, 0, sgWater,
"This body of water is calm and beautiful, but too deep to pass.")
MONSTER( 'P', 0xC08080, "Pike", moPike, CF_FACE_SIDE | CF_SHARK, RESERVED, moShark,
MONSTER( 'P', 0xC08080, "Pike", moPike, CF_FACE_SIDE | CF_NOBLOW | CF_SHARK, RESERVED, moShark,
"You remember anglers from your hometown showing the impressive pikes they have caught. This one is much larger."
)
MONSTER( 'T', 0xFF00FF, "World Turtle", moWorldTurtle, CF_FACE_SIDE | CF_STUNNABLE | CF_SLOWMOVER | CF_SPAM, RESERVED, moYeti,

View File

@ -19,6 +19,36 @@ bool sameland(eLand ll, eLand ln) {
return false;
}
cell *cellToTarget() {
if (isCrossroads(cwt.at->land)) {
for (cell *c: dcal) {
if (c->land == laCamelot && c->wall == waNone) {
printf("Trying to teleport into Camelot\n");
items[itOrbTeleport] += 1;
return c;
}
}
}
if(cwt.at->land == laCamelot) {
int oldDist = celldistAltRelative(cwt.at);
if (oldDist > 3) {
for (cell *c: dcal) {
if (c->land == laCamelot) {
int dist = celldistAltRelative(c);
if (-1 <= dist && dist <= 1 && hrand(10) == 0) {
printf("Trying to teleport near the round table (%d to %d)\n", oldDist, dist);
items[itOrbTeleport] += 1;
return c;
}
}
}
}
}
return dcal[hrand(isize(dcal))];
}
/* auto a3 = addHook(hooks_nextland, 100, [] (eLand l) {
eLand l2;
do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l);
@ -76,33 +106,108 @@ void autoplay(int num_moves = 1000000000) {
#endif
//mainloop();
}
int i = hrand(cwt.at->type);
cell *c2 = cwt.at->move(i);
/* if(gcount < 500) for(int i=1; i<isize(dcal); i++) {
c2 = dcal[i];
if(lcount >= 50 && !sameland(lland, c2->land) && !sameland(lland2, c2->land)) break;
else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break;
} */
items[hrand(ittypes)] = 1 << hrand(11);
kills[hrand(motypes)] = 1 << hrand(11);
items[itOrbYendor] &= 15;
again:
if(c2->cpdist > 1) {
for(int j=0; j<c2->type; j++)
if(c2->move(j) && c2->move(j)->cpdist < c2->cpdist) {
c2 = c2->move(j);
goto again;
}
// Use a random cheat
int croll = hrand(50);
if (croll < 25) {
eItem b = (eItem) hrand(ittypes);
printf("Gain item: %s\n", iinf[b].name);
items[b] = (1 << hrand(11)) - 1;
items[itOrbYendor] &= 15;
reduceOrbPowers(); // in particlar, cancel out slaying+weakness, since the combination may confuse shadow
} else if (croll == 25) {
printf("Gain kills\n");
kills[hrand(motypes)] = (1 << hrand(11)) - 1;
} else if (croll == 26) {
printf("Princess soon\n");
princess::saved = true;
princess::everSaved = true;
items[itSavedPrincess]++;
items[itOrbLove] = 1;
items[itOrbTime] = 0;
} else if (croll == 27) {
printf("Gain allies\n");
forCellEx(cz, cwt.at)
if (!cz->monst)
cz->monst = pick(moMouse, moFriendlyGhost, moGolem, moTameBomberbird, moKnight);
} else if (croll == 28) {
printf("Place orbs with pickup effects\n");
forCellEx(cz, cwt.at)
if (!cz->item)
cz->item = pick(itOrbLife, itOrbFriend, itOrbSpeed, itOrbShield, itOrbChaos, itOrbPurity);
} else if (croll == 29) {
printf("Place fun walls\n");
forCellEx(cz, cwt.at)
if (!cz->wall)
cz->wall = pick(waExplosiveBarrel, waBigStatue, waThumperOff, waBonfireOff, waCloud, waMirror);
} else if (croll == 30) {
cell *ct = dcal[hrand(isize(dcal))];
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
eWall hazard = pick(waRose, waFireTrap, waMineMine, waTrapdoor, waChasm, waCavewall);
printf("Spam a hazard: %s\n", winf[hazard].name);
ct->wall = hazard;
}
cwt.spin = 0;
int d = neighborId(cwt.at, c2);
if(d >= 0 && movepcto(d, 1, false))
println(hlog, "OK");
else {
println(hlog, "NOK");
killMonster(c2, moNone);
jumpTo(roKeyboard, c2, itNone, 0, moNone);
} else if (croll == 31 && !memory_saving_mode) {
//printf("Saving memory\n");
//memory_saving_mode = true;
//save_memory();
//memory_saving_mode = false;
} else if (croll == 33) {
cell *ct = dcal[hrand(isize(dcal))];
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
printf("Spam some slime\n");
ct->item = itNone;
ct->wall = hrand(2) ? waFloorA : waFloorB;
ct->monst = hrand(2) ? moSlime : moNone;
}
}
// don't show warning dialogs
items[itWarning] = 1;
// Make a random move
int roll = hrand(50);
if (roll == 0) {
// drop dead orb
bool res = movepcto(MD_DROP, 1);
printf("DROP: %d\n", res);
} else if (roll < 5) {
// skip turn
bool res = movepcto(MD_WAIT, 1);
printf("WAIT: %d\n", res);
} else if (roll < 42) {
// move to or attack a neighbor cell
int i = hrand(cwt.at->type);
cell *c2 = cwt.at->move(i);
cwt.spin = 0;
int d = neighborId(cwt.at, c2);
if (d >= 0) {
int subdir = (roll%2==0)?1:-1;
string c2info = dnameof(c2->wall) + "; " + dnameof(c2->monst) + "; " + dnameof(c2->item);
bool res = movepcto(d, subdir, false);
printf("MOVE %d [%s] sub %d: %d\n", d, c2info.c_str(), subdir, res);
if (!res && c2->monst) {
printf("clearing the monster (%s)\n", minf[c2->monst].name);
killMonster(c2, moNone);
}
} else {
printf("MOVE CONFUSED %d\n", d);
return;
}
} else {
// try to use a ranged orb
cell *ct = cellToTarget();
eItem ti = targetRangedOrb(ct, roMouseForce);
const char *tm = (ti == eItem(-1)) ? "orb cannot be used (see message log)" : iinf[ti].name;
printf("TARGET %p: %s\n", (void*)ct, tm);
}
if(false) if(turncount % 5000 == 0) {
printf("cells travelled: %d\n", celldist(cwt.at));
@ -125,6 +230,10 @@ void autoplay(int num_moves = 1000000000) {
cellcount = 0;
activateSafety(laCrossroads);
// landlist[hrand(isize(landlist))]);
if (cellcount < 0) {
//printf("How did cellcount become negative?\n");
cellcount = 1;
}
}
if(cwt.at->land == laWestWall && cwt.at->landparam >= 30) {
@ -132,6 +241,32 @@ void autoplay(int num_moves = 1000000000) {
forCellEx(c2, cwt.at) c2->item = itOrbSafety;
}
if(isIcyLand(cwt.at)) {
float heat = HEAT(cwt.at);
// Checking for extreme values as well as NaNs and infinities
if (!(-1e10 < heat && heat < 1e10)) {
printf("Heat is out of expected range\n");
canmove = true;
doAutoplay = false;
}
}
if (cwt.at->land == laCamelot) {
for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i];
if(c->land == laCamelot && celldistAltRelative(c) == 0 && c->wall != waRoundTable) {
printf("The round table of camelot has been breached!\n");
kills[moPlayer] = 0;
canmove = true;
doAutoplay = false;
}
}
}
if(cwt.at->monst && !isMultitile(cwt.at->monst)) {
printf("on a non-multitile monster: %s\n", minf[cwt.at->monst].name);
}
for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i];
if(isChild(c, NULL)) {
@ -143,6 +278,12 @@ void autoplay(int num_moves = 1000000000) {
canmove = true;
doAutoplay = false;
}
if(c->item == itBuggy || c->item == itBuggy2) {
printf("buggy item found\n");
kills[moPlayer] = 0;
canmove = true;
doAutoplay = false;
}
}
if(buggyGeneration || isize(buggycells)) {

View File

@ -430,7 +430,7 @@ EX bool canPushThumperOn(movei mi, cell *player) {
return
passable(tgt, thumper, P_MIRROR) &&
passable(tgt, player, P_MIRROR) &&
!tgt->item;
(!tgt->item || dice::on(thumper));
}
EX void activateActiv(cell *c, bool msg) {
@ -503,7 +503,7 @@ EX bool sameMonster(cell *c1, cell *c2) {
EX eMonster haveMount() {
for(cell *pc: player_positions()) {
eMonster m = pc->monst;
if(m) return m;
if(isWorm(m)) return m;
}
return moNone;
}

View File

@ -268,6 +268,7 @@ EX bool incompatible1(eLand l1, eLand l2) {
if(l1 == laDeadCaves && l2 == laCaves) return true;
if(l1 == laWarpSea && l2 == laKraken) return true;
if(l1 == laPrairie && l2 == laCrossroads3) return true;
if(l1 == laPrairie && l2 == laCrossroads4) return true;
if(l1 == laWet && l2 == laDesert) return true;
if(l1 == laFrog && l2 == laMotion) return true;
if(isElemental(l1) && isElemental(l2)) return true;

View File

@ -41,7 +41,7 @@ EX void showOverview() {
mouseovers += XLAT(" Hell: %1/%2", its(orbsUnlocked()), its(lands_for_hell()));
}
bool pages;
bool pages = false;
{
dynamicval<int> ds(dual::state, dual::state ? 2 : 0);

View File

@ -659,7 +659,7 @@ EX void beastAttack(cell *c, bool player, bool targetdir) {
if(c2->monst && c2->stuntime) {
cellwalker bull (c, d);
int subdir = determinizeBullPush(bull);
auto mi = determinePush(bull, subdir, [c2] (movei mi) { return passable(mi.t, c2, P_BLOW); });
auto mi = determinePush(bull, subdir, [c2] (movei mi) { return passable(mi.t, c2, P_BLOW) && !isPlayerOn(mi.t); });
if(mi.proper())
pushMonster(mi);
}

View File

@ -115,7 +115,7 @@ EX void reduceOrbPowerAlways(eItem it) {
EX void reverse_curse(eItem curse, eItem orb, bool cancel) {
if(items[curse] && markOrb(itOrbPurity)) {
items[orb] += items[curse];
if(curse == itCurseWeakness) items[itOrbWinter] += items[curse];
if(curse == itCurseWater) items[itOrbWinter] += items[curse];
items[curse] = 0;
}
if(cancel && items[curse] && items[orb]) {
@ -1211,6 +1211,7 @@ EX void apply_impact(cell *c) {
if(markOrb(itOrbImpact))
forCellEx(c1, c) {
if(!c1->monst) continue;
if(c1->monst == moMimic) continue;
if(isMultitile(c1->monst)) continue;
addMessage(XLAT("You stun %the1!", c1->monst));
changes.ccell(c1);
@ -1462,7 +1463,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
}
// (5c) stun
if(items[itOrbStunning] && c->monst && !isMultitile(c->monst) && c->stuntime < 3 && !shmup::on) {
if(items[itOrbStunning] && c->monst && !isMultitile(c->monst) && c->monst != moMimic && c->stuntime < 3 && !shmup::on) {
if(!isCheck(a)) stun_attack(c), apply_impact(c);
return itOrbStunning;
}
@ -1481,9 +1482,12 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
if(isWeakCheck(a)) return itNone;
if(nowhereToBlow) {
if(nowhereToBlow && isBlowableMonster(c->monst)) {
addMessage(XLAT("Nowhere to blow %the1!", c->monst));
}
else if(nowhereToBlow) {
addMessage(XLAT("Nowhere to blow %the1!", c->wall));
}
else if(jumpstate == 1 && jumpthru && jumpthru->monst) {
addMessage(XLAT("Cannot jump through %the1!", jumpthru->monst));
}

View File

@ -751,7 +751,7 @@ void pcmove::tell_why_cannot_attack() {
addMessage(XLAT("You cannot attack Sandworms directly!"));
else if(c2->monst == moHexSnake || c2->monst == moHexSnakeTail)
addMessage(XLAT("You cannot attack Rock Snakes directly!"));
else if(nonAdjacent(c2, cwt.at))
else if(nonAdjacentPlayer(c2, cwt.at))
addMessage(XLAT("You cannot attack diagonally!"));
else if(thruVine(c2, cwt.at))
addMessage(XLAT("You cannot attack through the Vine!"));
@ -785,6 +785,12 @@ void pcmove::tell_why_cannot_attack() {
addMessage(XLAT("You can only push this die if the highest number would be on the top!"));
else if(c2->monst == moAngryDie)
addMessage(XLAT("This die is really angry at you!"));
else if((attackflags & AF_WEAK) && isIvy(c2))
addMessage(XLAT("You are too weakened to attack %the1!", c2->monst));
else if(isWorm(cwt.at->monst) && isWorm(c2->monst) && wormhead(cwt.at) == wormhead(c2) && cwt.at->monst != moTentacleGhost && c2->monst != moTentacleGhost)
addMessage(XLAT("You cannot attack your own mount!"));
else if(checkOrb(c2->monst, itOrbShield))
addMessage(XLAT("A magical shield protects %the1!", c2->monst));
else
addMessage(XLAT("For some reason... cannot attack!"));
}
@ -929,7 +935,7 @@ bool pcmove::move_if_okay() {
void pcmove::tell_why_impassable() {
cell*& c2 = mi.t;
if(nonAdjacent(cwt.at,c2)) {
if(nonAdjacentPlayer(cwt.at,c2)) {
if(vmsg(miRESTRICTED)) addMessage(geosupport_football() < 2 ?
XLAT("You cannot move between the cells without dots here!") :
XLAT("You cannot move between the triangular cells here!")