1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-01-13 10:50:35 +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) { forCellEx(c1, c) {
changes.ccell(c1); changes.ccell(c1);
c1->item = itNone; 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; if(c1->wall == waDeadfloor) c1->wall = waCavefloor;
} }
} }
@ -1050,6 +1051,7 @@ EX void killFriendlyIvy() {
EX bool monsterPushable(cell *c2) { EX bool monsterPushable(cell *c2) {
if(markOrb(itCurseWeakness) && (c2->stuntime < 2 || attackJustStuns(c2, 0, moPlayer))) return false; 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); 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; 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) { if(c->mondir < c->type) {
vid.linewidth *= 3; vid.linewidth *= 3;
queueline(V*C0, V*currentmap->adj(c, c->mondir) * C0, 0xFFD500FF, 4); 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; int res = 0;
bool fast = false; bool fast = false;
bool kraken_will_destroy_boat = false;
elec::builder b; elec::builder b;
if(elec::affected(c)) { who_kills_me = moLightningBolt; res++; } 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]) { if(who == moPlayer || items[itOrbEmpathy]) {
fast = (items[itOrbSpeed] && (items[itOrbSpeed] & 1)); 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) { if(havewhat&HF_OUTLAW) {
@ -167,10 +168,9 @@ EX bool monstersnear(cell *c, eMonster who) {
if(elec::affected(c2)) continue; if(elec::affected(c2)) continue;
if(fast && c2->monst != moWitchSpeed) continue; if(fast && c2->monst != moWitchSpeed) continue;
// Krakens just destroy boats // Krakens just destroy boats
if(c2->monst == moKrakenT && c->wall == waBoat) { if(who == moPlayer && c2->monst == moKrakenT && c->wall == waBoat) {
if(krakensafe(c)) continue; kraken_will_destroy_boat = true;
else if(warningprotection(XLAT("This move appears dangerous -- are you sure?")) && res == 0) m = moWarning; continue;
else continue;
} }
// they cannot attack through vines // they cannot attack through vines
if(!canAttack(c2, c2->monst, c, who, AF_NEXTTURN)) continue; 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) if(kraken_will_destroy_boat && !krakensafe(c) && warningprotection(XLAT("This move appears dangerous -- are you sure?"))) {
res = 0; if (res == 0) who_kills_me = moWarning;
res++;
if(who == moPlayer && res && markOrb2(itOrbDomination) && c->monst) } else {
res = 0; if(who == moPlayer && res && (markOrb2(itOrbShield) || markOrb2(itOrbShell)) && !eaten)
res = 0;
if(who == moPlayer && res && markOrb2(itOrbDomination) && c->monst)
res = 0;
}
return !!res; return !!res;
} }

View File

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

View File

@ -2349,7 +2349,7 @@ EX void livecaves() {
for(cell *c2: adj_minefield_cells(c)) { for(cell *c2: adj_minefield_cells(c)) {
eWall w = c2->wall; eWall w = c2->wall;
if(w == waDeadfloor) hv++, bringlife.push_back(c2); 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); hv--, bringlife.push_back(c2);
else if(w == waCavefloor) hv++; else if(w == waCavefloor) hv++;
else if(w == waCavewall) hv--; else if(w == waCavewall) hv--;
@ -2597,7 +2597,7 @@ EX }
EX namespace dragon { EX namespace dragon {
EX int whichturn; // which turn has the target been set on 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) { void pullback(cell *c) {
int maxlen = iteration_limit; int maxlen = iteration_limit;
@ -2977,6 +2977,7 @@ EX namespace kraken {
for(int i=0; i<isize(dcal); i++) { for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i]; cell *c = dcal[i];
if(c->monst == moKrakenT && !c->stuntime) forCellEx(c2, c) { if(c->monst == moKrakenT && !c->stuntime) forCellEx(c2, c) {
if (!logical_adjacent(c2,moKrakenT,c)) continue;
bool dboat = false; bool dboat = false;
if(c2->monst && canAttack(c, moKrakenT, c2, c2->monst, AF_ONLY_FBUG)) { if(c2->monst && canAttack(c, moKrakenT, c2, c2->monst, AF_ONLY_FBUG)) {
attackMonster(c2, AF_NORMAL | AF_MSG, c->monst); attackMonster(c2, AF_NORMAL | AF_MSG, c->monst);
@ -3467,6 +3468,7 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () {
clearing::score.clear(); clearing::score.clear();
tortoise::emap.clear(); tortoise::emap.clear();
tortoise::babymap.clear(); tortoise::babymap.clear();
dragon::target = NULL;
#if CAP_FIELD #if CAP_FIELD
prairie::lasttreasure = NULL; prairie::lasttreasure = NULL;
prairie::enter = NULL; prairie::enter = NULL;
@ -3510,6 +3512,7 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () {
} }
return false; return false;
}); });
set_if_removed(dragon::target, NULL);
#if CAP_FIELD #if CAP_FIELD
set_if_removed(prairie::lasttreasure, NULL); set_if_removed(prairie::lasttreasure, NULL);
set_if_removed(prairie::enter, 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; 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; }}, {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; }}, {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); } }, {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; }}, {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) else if(cryst)
s = crystal::get_table_boundary(); s = crystal::get_table_boundary();
#endif #endif
else if(!quotient) else if(!quotient && rad)
s = expansion.get_descendants(rad).get_str(100); s = expansion.get_descendants(rad).get_str(100);
if(s == "") { msgid++; goto retry; } if(s == "") { msgid++; goto retry; }
addMessage(XLAT("\"Our Table seats %1 Knights!\"", s)); addMessage(XLAT("\"Our Table seats %1 Knights!\"", s));
@ -470,7 +470,7 @@ EX void knightFlavorMessage(cell *c2) {
else if(cryst) else if(cryst)
s = crystal::get_table_volume(); s = crystal::get_table_volume();
#endif #endif
else if(!quotient) else if(!quotient && rad)
s = expansion.get_descendants(rad-1, expansion.diskid).get_str(100); s = expansion.get_descendants(rad-1, expansion.diskid).get_str(100);
if(s == "") { msgid++; goto retry; } if(s == "") { msgid++; goto retry; }
addMessage(XLAT("\"There are %1 floor tiles inside our Table!\"", s)); 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', 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', 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( '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." "This dangerous predator has killed many people, and has been sent to Cocytus."
) )
MONSTER( 'W', 0xFFFFFF, "Running Dog", moRunDog, CF_FACE_SIDE, RESERVED, moYeti, 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, MONSTER( 'P', 0xD00000, "Pirate", moPirate, CF_FACE_UP | CF_LEADER, RESERVED, moPirate,
"Just a typical hyperbolic pirate." ) "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 " 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.") "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 ) 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, " "Animated corpses of ancient Viking warriors. They are immune to mundane weapons, "
"but they can be destroyed by your Orb of the Sword." "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, 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 " "Vampire Bats don't attack normally, but they drain your magical powers if "
"they are at distance at most 2 from you." "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, WALL( '=', 0x0000A0, "deep water", waDeepWater, WF_WATER, RESERVED, 0, sgWater,
"This body of water is calm and beautiful, but too deep to pass.") "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." "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, 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; 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) { /* auto a3 = addHook(hooks_nextland, 100, [] (eLand l) {
eLand l2; eLand l2;
do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l); do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l);
@ -76,33 +106,108 @@ void autoplay(int num_moves = 1000000000) {
#endif #endif
//mainloop(); //mainloop();
} }
int i = hrand(cwt.at->type);
cell *c2 = cwt.at->move(i);
/* if(gcount < 500) for(int i=1; i<isize(dcal); i++) { /* if(gcount < 500) for(int i=1; i<isize(dcal); i++) {
c2 = dcal[i]; c2 = dcal[i];
if(lcount >= 50 && !sameland(lland, c2->land) && !sameland(lland2, c2->land)) break; if(lcount >= 50 && !sameland(lland, c2->land) && !sameland(lland2, c2->land)) break;
else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break; else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break;
} */ } */
items[hrand(ittypes)] = 1 << hrand(11);
kills[hrand(motypes)] = 1 << hrand(11); // Use a random cheat
items[itOrbYendor] &= 15; int croll = hrand(50);
again: if (croll < 25) {
if(c2->cpdist > 1) { eItem b = (eItem) hrand(ittypes);
for(int j=0; j<c2->type; j++) printf("Gain item: %s\n", iinf[b].name);
if(c2->move(j) && c2->move(j)->cpdist < c2->cpdist) { items[b] = (1 << hrand(11)) - 1;
c2 = c2->move(j); items[itOrbYendor] &= 15;
goto again; 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; } else if (croll == 31 && !memory_saving_mode) {
int d = neighborId(cwt.at, c2); //printf("Saving memory\n");
if(d >= 0 && movepcto(d, 1, false)) //memory_saving_mode = true;
println(hlog, "OK"); //save_memory();
else { //memory_saving_mode = false;
println(hlog, "NOK"); } else if (croll == 33) {
killMonster(c2, moNone); cell *ct = dcal[hrand(isize(dcal))];
jumpTo(roKeyboard, c2, itNone, 0, moNone); 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) { if(false) if(turncount % 5000 == 0) {
printf("cells travelled: %d\n", celldist(cwt.at)); printf("cells travelled: %d\n", celldist(cwt.at));
@ -125,6 +230,10 @@ void autoplay(int num_moves = 1000000000) {
cellcount = 0; cellcount = 0;
activateSafety(laCrossroads); activateSafety(laCrossroads);
// landlist[hrand(isize(landlist))]); // 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) { 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; 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++) { for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i]; cell *c = dcal[i];
if(isChild(c, NULL)) { if(isChild(c, NULL)) {
@ -143,6 +278,12 @@ void autoplay(int num_moves = 1000000000) {
canmove = true; canmove = true;
doAutoplay = false; 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)) { if(buggyGeneration || isize(buggycells)) {

View File

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

View File

@ -268,6 +268,7 @@ EX bool incompatible1(eLand l1, eLand l2) {
if(l1 == laDeadCaves && l2 == laCaves) return true; if(l1 == laDeadCaves && l2 == laCaves) return true;
if(l1 == laWarpSea && l2 == laKraken) return true; if(l1 == laWarpSea && l2 == laKraken) return true;
if(l1 == laPrairie && l2 == laCrossroads3) 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 == laWet && l2 == laDesert) return true;
if(l1 == laFrog && l2 == laMotion) return true; if(l1 == laFrog && l2 == laMotion) return true;
if(isElemental(l1) && isElemental(l2)) 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())); 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); 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) { if(c2->monst && c2->stuntime) {
cellwalker bull (c, d); cellwalker bull (c, d);
int subdir = determinizeBullPush(bull); 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()) if(mi.proper())
pushMonster(mi); pushMonster(mi);
} }

View File

@ -115,7 +115,7 @@ EX void reduceOrbPowerAlways(eItem it) {
EX void reverse_curse(eItem curse, eItem orb, bool cancel) { EX void reverse_curse(eItem curse, eItem orb, bool cancel) {
if(items[curse] && markOrb(itOrbPurity)) { if(items[curse] && markOrb(itOrbPurity)) {
items[orb] += items[curse]; items[orb] += items[curse];
if(curse == itCurseWeakness) items[itOrbWinter] += items[curse]; if(curse == itCurseWater) items[itOrbWinter] += items[curse];
items[curse] = 0; items[curse] = 0;
} }
if(cancel && items[curse] && items[orb]) { if(cancel && items[curse] && items[orb]) {
@ -1211,6 +1211,7 @@ EX void apply_impact(cell *c) {
if(markOrb(itOrbImpact)) if(markOrb(itOrbImpact))
forCellEx(c1, c) { forCellEx(c1, c) {
if(!c1->monst) continue; if(!c1->monst) continue;
if(c1->monst == moMimic) continue;
if(isMultitile(c1->monst)) continue; if(isMultitile(c1->monst)) continue;
addMessage(XLAT("You stun %the1!", c1->monst)); addMessage(XLAT("You stun %the1!", c1->monst));
changes.ccell(c1); changes.ccell(c1);
@ -1462,7 +1463,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
} }
// (5c) stun // (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); if(!isCheck(a)) stun_attack(c), apply_impact(c);
return itOrbStunning; return itOrbStunning;
} }
@ -1481,9 +1482,12 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
if(isWeakCheck(a)) return itNone; if(isWeakCheck(a)) return itNone;
if(nowhereToBlow) { if(nowhereToBlow && isBlowableMonster(c->monst)) {
addMessage(XLAT("Nowhere to blow %the1!", 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) { else if(jumpstate == 1 && jumpthru && jumpthru->monst) {
addMessage(XLAT("Cannot jump through %the1!", 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!")); addMessage(XLAT("You cannot attack Sandworms directly!"));
else if(c2->monst == moHexSnake || c2->monst == moHexSnakeTail) else if(c2->monst == moHexSnake || c2->monst == moHexSnakeTail)
addMessage(XLAT("You cannot attack Rock Snakes directly!")); 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!")); addMessage(XLAT("You cannot attack diagonally!"));
else if(thruVine(c2, cwt.at)) else if(thruVine(c2, cwt.at))
addMessage(XLAT("You cannot attack through the Vine!")); 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!")); addMessage(XLAT("You can only push this die if the highest number would be on the top!"));
else if(c2->monst == moAngryDie) else if(c2->monst == moAngryDie)
addMessage(XLAT("This die is really angry at you!")); 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 else
addMessage(XLAT("For some reason... cannot attack!")); addMessage(XLAT("For some reason... cannot attack!"));
} }
@ -929,7 +935,7 @@ bool pcmove::move_if_okay() {
void pcmove::tell_why_impassable() { void pcmove::tell_why_impassable() {
cell*& c2 = mi.t; cell*& c2 = mi.t;
if(nonAdjacent(cwt.at,c2)) { if(nonAdjacentPlayer(cwt.at,c2)) {
if(vmsg(miRESTRICTED)) addMessage(geosupport_football() < 2 ? if(vmsg(miRESTRICTED)) addMessage(geosupport_football() < 2 ?
XLAT("You cannot move between the cells without dots here!") : XLAT("You cannot move between the cells without dots here!") :
XLAT("You cannot move between the triangular cells here!") XLAT("You cannot move between the triangular cells here!")