mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2026-05-08 00:01:24 +00:00
after 3 illegal moves, provide some suggestions regarding possible skip-moves and Orb uses
This commit is contained in:
@@ -404,8 +404,10 @@ int yasc_recode(int x) {
|
||||
return yasc_recode(x / 10) * 100 + (x % 10);
|
||||
};
|
||||
|
||||
EX void checkmove() {
|
||||
EX cell *bowtarget = nullptr;
|
||||
|
||||
EX void checkmove(bool complete) {
|
||||
if(!complete) { attempts = 0; movehints_ticks = 0; }
|
||||
if(dual::state == 2) return;
|
||||
if(shmup::on) return;
|
||||
|
||||
@@ -421,7 +423,7 @@ EX void checkmove() {
|
||||
legalmoves.clear(); legalmoves.resize(cwt.at->type+1, false);
|
||||
move_issues.clear(); move_issues.resize(cwt.at->type);
|
||||
|
||||
canmove = haveRangedTarget();
|
||||
canmove = haveRangedTarget(complete);
|
||||
items[itWarning]+=2;
|
||||
if(movepcto(-1, 0, true))
|
||||
canmove = legalmoves[cwt.at->type] = true;
|
||||
@@ -450,7 +452,9 @@ EX void checkmove() {
|
||||
for(int i=0; i<cwt.at->type; i++)
|
||||
yasc_code += yasc_recode(move_issues[i].type);
|
||||
|
||||
if(!canmove && bow::crossbow_mode() && !items[itCrossbow]) canmove = bow::have_bow_target();
|
||||
bowtarget = (!canmove || complete) ? bow::have_bow_target() : nullptr;
|
||||
|
||||
if(bowtarget) canmove = true;
|
||||
|
||||
#if CAP_INV
|
||||
if(inv::on && !canmove && !inv::incheck) {
|
||||
@@ -458,7 +462,7 @@ EX void checkmove() {
|
||||
canmove = true;
|
||||
else {
|
||||
inv::check(1);
|
||||
checkmove();
|
||||
checkmove(complete);
|
||||
inv::check(-1);
|
||||
}
|
||||
if(canmove)
|
||||
|
||||
@@ -4299,7 +4299,7 @@ EX void configureMouse() {
|
||||
dialog::add_action([] {
|
||||
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), XLAT("0 to disable"));
|
||||
// we need to check the moves
|
||||
dialog::get_di().reaction = checkmove;
|
||||
dialog::get_di().reaction = [] { checkmove(false); };
|
||||
dialog::bound_low(0);
|
||||
});
|
||||
|
||||
|
||||
@@ -517,7 +517,10 @@ EX void shoot() {
|
||||
gen_bowpath_map();
|
||||
}
|
||||
|
||||
EX bool have_bow_target() {
|
||||
EX cell *have_bow_target() {
|
||||
if(!bow::crossbow_mode()) return nullptr;
|
||||
if(items[itCrossbow]) return nullptr;
|
||||
|
||||
dynamicval<decltype(bowpath)> bp(bowpath);
|
||||
dynamicval<decltype(bowpath_map)> bpm(bowpath_map);
|
||||
|
||||
@@ -536,9 +539,9 @@ EX bool have_bow_target() {
|
||||
bool b = pcm.try_shooting(false);
|
||||
changes.rollback();
|
||||
|
||||
if(b) return true;
|
||||
if(b) return c;
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EX void showMenu() {
|
||||
|
||||
@@ -901,7 +901,7 @@ EX void monstersTurn() {
|
||||
checkFreedom(pc);
|
||||
|
||||
DEBB(debug_turn, ("check"));
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
if(canmove) elec::checklightningfast();
|
||||
|
||||
|
||||
|
||||
2
game.cpp
2
game.cpp
@@ -215,7 +215,7 @@ EX bool activateRecall() {
|
||||
if(shmup::on) shmup::recall();
|
||||
if(multi::players > 1) multi::recall();
|
||||
bfs();
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
drawSafety();
|
||||
addMessage(XLAT("You are recalled!"));
|
||||
return true;
|
||||
|
||||
14
graph.cpp
14
graph.cpp
@@ -962,6 +962,20 @@ EX void drawMarkers() {
|
||||
viewmat();
|
||||
#endif
|
||||
|
||||
if(ticks < movehints_ticks) {
|
||||
if(legalmoves[cwt.at->type] && !vid.mobilecompasssize) queuecircleat(cwt.at, 0.5 + 0.25 * sintick(75), darkena(0xFFFFFF, 0, 0xFF));
|
||||
for(auto& p: orb_used_where) if(gmatrix.count(p.second))
|
||||
queuestr(gmatrix[p.second], mapfontscale/100, "X", gradient(0, iinf[p.first].color, -1, sintick(75), 1));
|
||||
if(bowtarget && gmatrix.count(bowtarget) && bowtarget->cpdist >= 2) {
|
||||
auto V = gmatrix[bowtarget];
|
||||
queuestr(V, mapfontscale/100, "X", gradient(0, iinf[itCrossbow].color, -1, sintick(75), 1));
|
||||
poly_outline = gradient(0, getcs().bowcolor, -1, sintick(75), 1);
|
||||
queuepolyat(V, cgi.shCrossbowIcon, 0, PPR::LINE);
|
||||
poly_outline = gradient(0, getcs().bowcolor2, -1, sintick(75), 1);
|
||||
queuepolyat(V, cgi.shCrossbowstringIcon, 0, PPR::LINE);
|
||||
}
|
||||
}
|
||||
|
||||
#if CAP_QUEUE
|
||||
for(cell *c1: crush_now)
|
||||
queuecircleat(c1, .8, darkena(minf[moCrusher].color, 0, 0xFF));
|
||||
|
||||
33
help.cpp
33
help.cpp
@@ -357,6 +357,24 @@ string power_help =
|
||||
"collected. This also affects the mirrorings which happened before "
|
||||
"collecting the Powerstones.";
|
||||
|
||||
EX string ranged_click_help() {
|
||||
string s;
|
||||
#if ISMOBILE
|
||||
if(vid.shifttarget&2)
|
||||
s = XLAT("\nRanged Orbs can be targeted by long touching the desired location.");
|
||||
else
|
||||
s = XLAT("\nRanged Orbs can be targeted by touching the desired location.");
|
||||
#else
|
||||
if(vid.shifttarget&1)
|
||||
s = XLAT("\nRanged Orbs can be targeted by shift-clicking the desired location. ");
|
||||
else
|
||||
s = XLAT("\nRanged Orbs can be targeted by clicking the desired location. ");
|
||||
if(DEFAULTCONTROL)
|
||||
s += XLAT("You can also scroll to the desired location and then press 't'.");
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
EX string generateHelpForItem(eItem it) {
|
||||
|
||||
string help = helptitle(XLATN(iinf[it].name), iinf[it].color);
|
||||
@@ -401,19 +419,8 @@ EX string generateHelpForItem(eItem it) {
|
||||
#endif
|
||||
|
||||
if(isRangedOrb(it)) {
|
||||
help += XLAT("\nThis is a ranged Orb. ");
|
||||
#if ISMOBILE
|
||||
if(vid.shifttarget&2)
|
||||
help += XLAT("\nRanged Orbs can be targeted by long touching the desired location.");
|
||||
else
|
||||
help += XLAT("\nRanged Orbs can be targeted by touching the desired location.");
|
||||
#else
|
||||
if(vid.shifttarget&1)
|
||||
help += XLAT("\nRanged Orbs can be targeted by shift-clicking the desired location. ");
|
||||
else
|
||||
help += XLAT("\nRanged Orbs can be targeted by clicking the desired location. ");
|
||||
help += XLAT("You can also scroll to the desired location and then press 't'.");
|
||||
#endif
|
||||
help += XLAT("\nThis is a ranged Orb. \n");
|
||||
help += ranged_click_help();
|
||||
help += XLAT("\nYou can never target cells which are adjacent to the player character, or ones out of the sight range.");
|
||||
}
|
||||
|
||||
|
||||
@@ -687,7 +687,7 @@ EX namespace inv {
|
||||
usedForbidden = true;
|
||||
cwt.at->item = it;
|
||||
evokeOrb(orbmap[uni]);
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
popScreenAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ EX void showOverview() {
|
||||
dialog::helpToEdit(items[umod], 0, 200, 10, 10);
|
||||
dialog::get_ne().reaction = [] () {
|
||||
if(hardcore) canmove = true;
|
||||
else checkmove();
|
||||
else checkmove(false);
|
||||
cheater++;
|
||||
};
|
||||
dialog::bound_low(0);
|
||||
|
||||
@@ -1024,7 +1024,7 @@ EX void handleInput(int delta, config &scfg) {
|
||||
}
|
||||
if(multi::activePlayers() == 1) {
|
||||
multi::checkonly = true;
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
multi::checkonly = false;
|
||||
}
|
||||
}
|
||||
|
||||
13
orbs.cpp
13
orbs.cpp
@@ -603,15 +603,20 @@ EX void activateLightning() {
|
||||
// roMouse/roKeyboard:
|
||||
// return orb type if successful, eItem(-1) if do nothing, 0 otherwise
|
||||
|
||||
EX bool haveRangedTarget() {
|
||||
EX map<eItem, cell*> orb_used_where;
|
||||
|
||||
EX bool haveRangedTarget(bool complete) {
|
||||
orb_used_where.clear();
|
||||
if(!haveRangedOrb())
|
||||
return false;
|
||||
for(int i=0; i<isize(dcal); i++) {
|
||||
cell *c = dcal[i];
|
||||
if(targetRangedOrb(c, roCheck)) {
|
||||
return true;
|
||||
if(eItem it = targetRangedOrb(c, roCheck)) {
|
||||
if(complete && !orb_used_where.count(it)) orb_used_where[it] = c;
|
||||
else return true;
|
||||
}
|
||||
}
|
||||
if(complete) return orb_used_where.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -619,7 +624,7 @@ void checkmoveO() {
|
||||
bow::bowpath_map.clear();
|
||||
if(multi::players > 1 && multi::activePlayers() == 1)
|
||||
multi::checklastmove();
|
||||
if(multi::players == 1) checkmove();
|
||||
if(multi::players == 1) checkmove(false);
|
||||
}
|
||||
|
||||
int teleportAction() {
|
||||
|
||||
45
pcmove.cpp
45
pcmove.cpp
@@ -273,6 +273,9 @@ bool pcmove::vmsg(moveissue mi) {
|
||||
return errormsgs && !checkonly;
|
||||
}
|
||||
|
||||
EX int attempts = 0;
|
||||
EX int movehints_ticks = 0;
|
||||
|
||||
EX bool movepcto(int d, int subdir IS(1), bool checkonly IS(false)) {
|
||||
checked_move_issue.type = miVALID;
|
||||
pcmove pcm;
|
||||
@@ -281,6 +284,40 @@ EX bool movepcto(int d, int subdir IS(1), bool checkonly IS(false)) {
|
||||
pcm.subdir = subdir;
|
||||
auto b = pcm.movepcto();
|
||||
global_pushto = pcm.mip.t;
|
||||
if(!checkonly && !b && multi::players == 1) {
|
||||
attempts++;
|
||||
if(attempts == 3) {
|
||||
attempts = 0;
|
||||
checkmove(true);
|
||||
movehints_ticks = ticks + 1000;
|
||||
if(legalmoves[cwt.at->type]) {
|
||||
if(!DEFAULTCONTROL) addMessage(XLAT("You can skip your turn."));
|
||||
#if ISMOBILE
|
||||
else if(vid.mobilecompasssize) addMessage(XLAT("Touch the center of the compass to skip your turn."));
|
||||
#else
|
||||
else if(vid.mobilecompasssize) addMessage(XLAT("Click the center of the compass to skip your turn."));
|
||||
#endif
|
||||
else if(dialog::display_keys == 3) addMessage(XLAT("Press Ⓐ to skip your turn."));
|
||||
else if(dialog::actual_display_keys()) addMessage(XLAT("Press . or s to skip your turn."));
|
||||
#if ISMOBILE
|
||||
else if(true) addMessage(XLAT("Touch the Rogue to skip your turn."));
|
||||
#endif
|
||||
else addMessage(XLAT("Click the Rogue to skip your turn."));
|
||||
if(among(cwt.at->land, laPalace, laCaves, laWarpCoast, laWarpSea))
|
||||
addMessage(XLAT("Wait about 100 turns to let the ghosts decide your fate."));
|
||||
}
|
||||
println(hlog, "orb_used_where = ", orb_used_where);
|
||||
if(orb_used_where.size() == 1)
|
||||
addMessage(XLAT("You can use your %1.\n", orb_used_where.begin()->first));
|
||||
else if(orb_used_where.size() > 1) {
|
||||
string txt;
|
||||
for(auto x: orb_used_where) { if(txt != "") txt += ", "; txt += dnameof(x.first); }
|
||||
addMessage(XLAT("You can use: %1.\n", txt));
|
||||
}
|
||||
if(orb_used_where.size()) addMessage(ranged_click_help());
|
||||
if(bowtarget && bowtarget->cpdist >= 2) addMessage(XLAT("You have a bow target."));
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -322,7 +359,7 @@ bool pcmove::try_shooting(bool auto_target) {
|
||||
if(checkonly) return true;
|
||||
if(changes.on) changes.commit();
|
||||
addMessage(XLAT("(shooting while unstable -- no turn passes)"));
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -428,7 +465,7 @@ bool pcmove::movepcto() {
|
||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
||||
if(warning_shown || orbProtection(itOrbFlash)) return true;
|
||||
activateFlash();
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -436,7 +473,7 @@ bool pcmove::movepcto() {
|
||||
if(checkonly) { nextmovetype = lmInstant; return true; }
|
||||
if(warning_shown || orbProtection(itOrbLightning)) return true;
|
||||
activateLightning();
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -520,7 +557,7 @@ bool pcmove::after_instant(bool kl) {
|
||||
bfs();
|
||||
keepLightning = false;
|
||||
if(multi::players > 1) { multi::whereto[multi::cpid].d = MD_UNDECIDED; return false; }
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ EX void initgame() {
|
||||
|
||||
lastsafety = gold();
|
||||
bfs();
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
playermoved = true;
|
||||
|
||||
if(quotient || sphere)
|
||||
@@ -1533,6 +1533,7 @@ EX void stop_game() {
|
||||
#endif
|
||||
// items[itGreenStone] = 100;
|
||||
game_active = false;
|
||||
movehints_ticks = 0;
|
||||
clearMemory();
|
||||
#if CAP_DAILY
|
||||
if(daily::on)
|
||||
|
||||
4
tour.cpp
4
tour.cpp
@@ -414,12 +414,12 @@ EX bool handleKeyTour(int sym, int uni) {
|
||||
popScreenAll();
|
||||
if(items[itOrbTeleport]) goto give_aether;
|
||||
items[itOrbTeleport] = 1;
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
if(!canmove) {
|
||||
if(items[itOrbAether]) goto give_flash;
|
||||
give_aether:
|
||||
items[itOrbAether] = 10;
|
||||
checkmove();
|
||||
checkmove(false);
|
||||
if(!canmove) {
|
||||
give_flash:
|
||||
activateFlash();
|
||||
|
||||
Reference in New Issue
Block a user