+ if (conditions[game.loc] >= game.conds) {
+ for (int hint = 0; hint < NHINTS; hint++) {
+ if (game.hinted[hint])
+ continue;
+ if (!CNDBIT(game.loc, hint + 1 + COND_HBASE))
+ game.hintlc[hint] = -1;
+ ++game.hintlc[hint];
+ /* Come here if he's been long enough at required loc(s) for some
+ * unused hint. */
+ if (game.hintlc[hint] >= hints[hint].turns) {
+ int i;
+
+ switch (hint) {
+ case 0:
+ /* cave */
+ if (game.prop[GRATE] == GRATE_CLOSED && !HERE(KEYS))
+ break;
+ game.hintlc[hint] = 0;
+ return;
+ case 1: /* bird */
+ if (game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD)
+ break;
+ return;
+ case 2: /* snake */
+ if (HERE(SNAKE) && !HERE(BIRD))
+ break;
+ game.hintlc[hint] = 0;
+ return;
+ case 3: /* maze */
+ if (game.atloc[game.loc] == 0 &&
+ game.atloc[game.oldloc] == 0 &&
+ game.atloc[game.oldlc2] == 0 &&
+ game.holdng > 1)
+ break;
+ game.hintlc[hint] = 0;
+ return;
+ case 4: /* dark */
+ if (game.prop[EMERALD] != -1 && game.prop[PYRAMID] == -1)
+ break;
+ game.hintlc[hint] = 0;
+ return;
+ case 5: /* witt */
+ break;
+ case 6: /* urn */
+ if (game.dflag == 0)
+ break;
+ game.hintlc[hint] = 0;
+ return;
+ case 7: /* woods */
+ if (game.atloc[game.loc] == 0 &&
+ game.atloc[game.oldloc] == 0 &&
+ game.atloc[game.oldlc2] == 0)
+ break;
+ return;
+ case 8: /* ogre */
+ i = atdwrf(game.loc);
+ if (i < 0) {
+ game.hintlc[hint] = 0;
+ return;
+ }
+ if (HERE(OGRE) && i == 0)
+ break;
+ return;
+ case 9: /* jade */
+ if (game.tally == 1 && game.prop[JADE] < 0)
+ break;
+ game.hintlc[hint] = 0;
+ return;
+ default:
+ BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST);
+ break;
+ }
+
+ /* Fall through to hint display */
+ game.hintlc[hint] = 0;
+ if (!yes(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN]))
+ return;
+ rspeak(HINT_COST, hints[hint].penalty, hints[hint].penalty);
+ game.hinted[hint] = yes(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]);
+ if (game.hinted[hint] && game.limit > WARNTIME)
+ game.limit += WARNTIME * hints[hint].penalty;
+ }
+ }
+ }
+}
+
+static bool spotted_by_pirate(int i)
+{
+ if (i != PIRATE)
+ return false;
+
+ /* The pirate's spotted him. He leaves him alone once we've
+ * found chest. K counts if a treasure is here. If not, and
+ * tally=1 for an unseen chest, let the pirate be spotted. Note
+ * that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown
+ * it to the troll, but in that case he's seen the chest
+ * (game.prop=0). */
+ if (game.loc == game.chloc || game.prop[CHEST] >= 0)
+ return true;
+ int snarfed = 0;
+ bool movechest = false, robplayer = false;
+ for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
+ if (!objects[treasure].is_treasure)
+ continue;
+ /* Pirate won't take pyramid from plover room or dark
+ * room (too easy!). */
+ if (treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac)) {
+ continue;
+ }
+ if (TOTING(treasure) || HERE(treasure))
+ ++snarfed;
+ if (TOTING(treasure)) {
+ movechest = true;
+ robplayer = true;
+ }
+ }
+ /* Force chest placement before player finds last treasure */
+ if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == LOC_NOWHERE && HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT) {
+ rspeak(PIRATE_SPOTTED);
+ movechest = true;
+ }
+ /* Do things in this order (chest move before robbery) so chest is listed
+ * last at the maze location. */
+ if (movechest) {
+ move(CHEST, game.chloc);
+ move(MESSAG, game.chloc2);
+ game.dloc[PIRATE] = game.chloc;
+ game.odloc[PIRATE] = game.chloc;
+ game.dseen[PIRATE] = false;
+ } else {
+ /* You might get a hint of the pirate's presence even if the
+ * chest doesn't move... */
+ if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20))
+ rspeak(PIRATE_RUSTLES);
+ }
+ if (robplayer) {
+ rspeak(PIRATE_POUNCES);
+ for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
+ if (!objects[treasure].is_treasure)