1 /**
2  * @file
3  * @brief Functions for handling multi-turn actions.
4 **/
5 
6 #include "AppHdr.h"
7 
8 #include "delay.h"
9 
10 #include <cstdio>
11 #include <cstring>
12 
13 #include "ability.h"
14 #include "areas.h"
15 #include "artefact.h"
16 #include "bloodspatter.h"
17 #include "clua.h"
18 #include "command.h"
19 #include "coord.h"
20 #include "corpse.h"
21 #include "database.h"
22 #include "describe.h"
23 #include "directn.h"
24 #include "dungeon.h"
25 #include "english.h"
26 #include "env.h"
27 #include "fineff.h"
28 #include "fprop.h"
29 #include "god-companions.h"
30 #include "god-passive.h"
31 #include "god-wrath.h"
32 #include "hints.h"
33 #include "invent.h"
34 #include "item-prop.h"
35 #include "items.h"
36 #include "item-use.h"
37 #include "item-status-flag-type.h"
38 #include "libutil.h"
39 #include "macro.h"
40 #include "message.h"
41 #include "mon-act.h"
42 #include "mon-behv.h"
43 #include "mon-gear.h"
44 #include "mon-tentacle.h"
45 #include "mon-util.h"
46 #include "mutation.h"
47 #include "nearby-danger.h"
48 #include "notes.h"
49 #include "options.h"
50 #include "ouch.h"
51 #include "output.h"
52 #include "player-equip.h"
53 #include "player.h"
54 #include "prompt.h"
55 #include "random.h"
56 #include "religion.h"
57 #include "shout.h"
58 #include "sound.h"
59 #include "spl-selfench.h"
60 #include "spl-util.h"
61 #include "stairs.h"
62 #include "state.h"
63 #include "stringutil.h"
64 #include "teleport.h"
65 #include "terrain.h"
66 #include "timed-effects.h"
67 #include "transform.h"
68 #include "traps.h"
69 #include "travel.h"
70 #include "xom.h"
71 
72 int interrupt_block::interrupts_blocked = 0;
73 
74 static const char *_activity_interrupt_name(activity_interrupt ai);
75 
_eq_category(const item_def & equip)76 static string _eq_category(const item_def &equip)
77 {
78     return equip.base_type == OBJ_JEWELLERY ? "amulet" : "armour";
79 }
80 
push_delay(shared_ptr<Delay> delay)81 void push_delay(shared_ptr<Delay> delay)
82 {
83     if (delay->is_run())
84         clear_travel_trail();
85     for (auto i = you.delay_queue.begin(); i != you.delay_queue.end(); ++i)
86     {
87         if ((*i)->is_parent())
88         {
89             you.delay_queue.insert(i, delay);
90             you.redraw_evasion = true;
91             return;
92         }
93     }
94     you.delay_queue.push_back(delay);
95     you.redraw_evasion = true;
96 }
97 
_pop_delay()98 static void _pop_delay()
99 {
100     if (!you.delay_queue.empty())
101         you.delay_queue.erase(you.delay_queue.begin());
102 
103     you.redraw_evasion = true;
104 }
105 
_clear_pending_delays(size_t after_index=1)106 static void _clear_pending_delays(size_t after_index = 1)
107 {
108     while (you.delay_queue.size() > after_index)
109     {
110         auto delay = you.delay_queue.back();
111 
112         you.delay_queue.pop_back();
113 
114         if (delay->is_run() && you.running)
115             // If you got here, you're already clearing the delays and there's
116             // no need to clear them again.
117             stop_running(false);
118     }
119 }
120 
try_interrupt()121 bool MemoriseDelay::try_interrupt()
122 {
123     // Losing work here is okay... having to start from
124     // scratch is a reasonable behaviour. -- bwr
125     mpr("Your memorisation is interrupted.");
126     return true;
127 }
128 
try_interrupt()129 bool MultidropDelay::try_interrupt()
130 {
131     // No work lost
132     if (!items.empty())
133         mpr("You stop dropping stuff.");
134     return true;
135 }
136 
try_interrupt()137 bool BaseRunDelay::try_interrupt()
138 {
139     // Keep things consistent, otherwise disturbing phenomena can occur.
140     if (you.running)
141         stop_running(false);
142     update_turn_count();
143 
144     // Always interruptible.
145     return true;
146 }
147 
try_interrupt()148 bool MacroDelay::try_interrupt()
149 {
150     // Always interruptible.
151     return true;
152     // There's no special action needed for macros - if we don't call out
153     // to the Lua function, it can't do damage.
154 }
155 
try_interrupt()156 bool EquipOnDelay::try_interrupt()
157 {
158     if (duration > 1 && !was_prompted)
159     {
160         if (!crawl_state.disables[DIS_CONFIRMATIONS]
161             && !yesno("Keep equipping yourself?", false, 0, false))
162         {
163             mprf("You stop putting on your %s.", _eq_category(equip).c_str());
164             return true;
165         }
166         else
167             was_prompted = true;
168     }
169     return false;
170 }
171 
try_interrupt()172 bool EquipOffDelay::try_interrupt()
173 {
174     if (duration > 1 && !was_prompted)
175     {
176         if (!crawl_state.disables[DIS_CONFIRMATIONS]
177             && !yesno("Keep disrobing?", false, 0, false))
178         {
179             mprf("You stop removing your %s.", _eq_category(equip).c_str());
180             return true;
181         }
182         else
183             was_prompted = true;
184     }
185     return false;
186 }
187 
try_interrupt()188 bool AscendingStairsDelay::try_interrupt()
189 {
190     mpr("You stop ascending the stairs.");
191     return true;  // short... and probably what people want
192 }
193 
try_interrupt()194 bool DescendingStairsDelay::try_interrupt()
195 {
196     mpr("You stop descending the stairs.");
197     return true;  // short... and probably what people want
198 }
199 
try_interrupt()200 bool PasswallDelay::try_interrupt()
201 {
202     mpr("Your meditation is interrupted.");
203     return true;
204 }
205 
try_interrupt()206 bool ShaftSelfDelay::try_interrupt()
207 {
208     mpr("You stop digging.");
209     return true;
210 }
211 
try_interrupt()212 bool ExsanguinateDelay::try_interrupt()
213 {
214     if (duration > 1 && !was_prompted)
215     {
216         if (!crawl_state.disables[DIS_CONFIRMATIONS]
217             && !yesno("Keep bloodletting?", false, 0, false))
218         {
219             mpr("You stop emptying yourself of blood.");
220             return true;
221         }
222         else
223             was_prompted = true;
224     }
225     return false;
226 }
227 
try_interrupt()228 bool RevivifyDelay::try_interrupt()
229 {
230     if (duration > 1 && !was_prompted)
231     {
232         if (!crawl_state.disables[DIS_CONFIRMATIONS]
233             && !yesno("Continue your ritual?", false, 0, false))
234         {
235             mpr("You stop revivifying.");
236             return true;
237         }
238         else
239             was_prompted = true;
240     }
241     return false;
242 }
243 
stop_delay(bool stop_stair_travel)244 void stop_delay(bool stop_stair_travel)
245 {
246     if (you.delay_queue.empty())
247         return;
248 
249     set_more_autoclear(false);
250 
251     ASSERT(!crawl_state.game_is_arena());
252 
253     auto delay = current_delay();
254 
255     // At the very least we can remove any queued delays, right
256     // now there is no problem with doing this... note that
257     // any queuing here can only happen from a single command,
258     // as the effect of a delay doesn't normally allow interaction
259     // until it is done... it merely chains up individual actions
260     // into a single action.  -- bwr
261     // Butcher delays do this on their own, in order to determine the old
262     // list of delays before clearing it.
263     _clear_pending_delays();
264 
265     if ((!delay->is_stair_travel() || stop_stair_travel)
266         && delay->try_interrupt())
267     {
268         _pop_delay();
269     }
270 }
271 
you_are_delayed()272 bool you_are_delayed()
273 {
274     return !you.delay_queue.empty();
275 }
276 
current_delay()277 shared_ptr<Delay> current_delay()
278 {
279     return you_are_delayed() ? you.delay_queue.front()
280                              : nullptr;
281 }
282 
player_stair_delay()283 bool player_stair_delay()
284 {
285     auto delay = current_delay();
286     return delay && delay->is_stairs();
287 }
288 
289 /**
290  * Is the player currently in the middle of memorising a spell?
291  *
292  * @param spell     A specific spell, or -1 to check if we're memorising any
293  *                  spell at all.
294  * @return          Whether the player is currently memorising the given type
295  *                  of spell.
296  */
already_learning_spell(int spell)297 bool already_learning_spell(int spell)
298 {
299     for (const auto &delay : you.delay_queue)
300     {
301         auto mem = dynamic_cast<MemoriseDelay*>(delay.get());
302         if (!mem)
303             continue;
304 
305         if (spell == -1 || mem->spell == spell)
306             return true;
307     }
308     return false;
309 }
310 
_get_running_command()311 static command_type _get_running_command()
312 {
313     if (Options.travel_key_stop && kbhit()
314         || !in_bounds(you.pos() + you.running.pos))
315     {
316         stop_running();
317         return CMD_NO_CMD;
318     }
319 
320     if (is_resting())
321     {
322         you.running.rest();
323 
324 #ifdef USE_TILE
325         if (Options.rest_delay >= 0 && tiles.need_redraw())
326             tiles.redraw();
327 #endif
328 
329         if (!is_resting() && you.running.hp == you.hp
330             && you.running.mp == you.magic_points)
331         {
332             mpr("Done waiting.");
333         }
334 
335         if (Options.rest_delay > 0)
336             delay(Options.rest_delay);
337 
338         return CMD_WAIT;
339     }
340     else if (you.running.is_explore() && Options.explore_delay > -1)
341         delay(Options.explore_delay);
342     else if (Options.travel_delay > 0)
343         delay(Options.travel_delay);
344 
345     return direction_to_command(you.running.pos.x, you.running.pos.y);
346 }
347 
clear_macro_process_key_delay()348 void clear_macro_process_key_delay()
349 {
350     if (dynamic_cast<MacroProcessKeyDelay*>(current_delay().get()))
351         _pop_delay();
352 }
353 
start()354 void EquipOnDelay::start()
355 {
356     mprf(MSGCH_MULTITURN_ACTION, "You start putting on your %s.",
357          _eq_category(equip).c_str());
358 }
359 
start()360 void EquipOffDelay::start()
361 {
362     mprf(MSGCH_MULTITURN_ACTION, "You start removing your %s.",
363          _eq_category(equip).c_str());
364 }
365 
start()366 void MemoriseDelay::start()
367 {
368     if (vehumet_is_offering(spell))
369     {
370         string message = make_stringf(" grants you knowledge of %s.",
371             spell_title(spell));
372         simple_god_message(message.c_str());
373     }
374     mprf(MSGCH_MULTITURN_ACTION, "You start memorising the spell.");
375 }
376 
start()377 void PasswallDelay::start()
378 {
379     mprf(MSGCH_MULTITURN_ACTION, "You begin to meditate on the wall.");
380 }
381 
start()382 void ShaftSelfDelay::start()
383 {
384     mprf(MSGCH_MULTITURN_ACTION, "You begin to dig a shaft.");
385 }
386 
start()387 void ExsanguinateDelay::start()
388 {
389     mprf(MSGCH_MULTITURN_ACTION, "You begin bloodletting.");
390 }
391 
start()392 void RevivifyDelay::start()
393 {
394     mprf(MSGCH_MULTITURN_ACTION, "You begin the revivification ritual.");
395 }
396 
move_cmd() const397 command_type RunDelay::move_cmd() const
398 {
399     return _get_running_command();
400 }
401 
move_cmd() const402 command_type RestDelay::move_cmd() const
403 {
404     return _get_running_command();
405 }
406 
move_cmd() const407 command_type TravelDelay::move_cmd() const
408 {
409     return travel();
410 }
411 
handle()412 void BaseRunDelay::handle()
413 {
414     bool first_move = false;
415     if (!started)
416     {
417         first_move = true;
418         started = true;
419     }
420     // Handle inconsistencies between the delay queue and you.running.
421     // We don't want to send the game into a deadlock.
422     if (!you.running)
423     {
424         update_turn_count();
425         _pop_delay();
426         return;
427     }
428 
429     if (you.turn_is_over)
430         return;
431 
432     command_type cmd = CMD_NO_CMD;
433 
434     if ((want_move() && you.confused()) ||
435         (!(unsafe_once && first_move) && !i_feel_safe(true, want_move())))
436     {
437         stop_running();
438     }
439     else
440         cmd = move_cmd();
441 
442     if (cmd != CMD_NO_CMD)
443     {
444         if (want_clear_messages())
445             clear_messages();
446         process_command(cmd);
447         if (you.turn_is_over
448             && (you.running.is_any_travel() || you.running.is_rest()))
449         {
450             you.running.turns_passed++;
451             // sanity check: if we get up to a large number of turns on
452             // an explore, run, or rest delay, something is extremely buggy
453             // and we should both rescue the player, and generate a crash
454             // report. The thresholds are very heuristic:
455             // Rest delay, 500 turns. This is a bit more than 2x what it takes
456             // a maxed troll to heal.
457             // Travel delay, 2000. Just a big number that is quite a bit
458             // bigger than any travel delay I have been able to generate. If
459             // anyone can generate this on demand it should be raised. (Or
460             // eventually, removed?)
461             // For debuggers: runmode if negative is a meaningful delay type,
462             // but when positive is used as a counter, so if it's a very large
463             // number in the assert message, this is a wait delay
464 
465             const int buggy_threshold = you.running.is_rest()
466                 ? 500
467                 : (ZOT_CLOCK_PER_FLOOR / BASELINE_DELAY / 3);
468             ASSERTM(you.running.turns_passed < buggy_threshold,
469                     "Excessive delay, %d turns passed, delay type %d",
470                     you.running.turns_passed, you.running.runmode);
471         }
472     }
473 
474     if (!you.turn_is_over)
475         you.time_taken = 0;
476 
477     // If you.running has gone to zero, and the run delay was not
478     // removed, remove it now. This is needed to clean up after
479     // find_travel_pos() function in travel.cc.
480     if (!you.running
481         && !you.delay_queue.empty()
482         && you.delay_queue.front()->is_run())
483     {
484         update_turn_count();
485         _pop_delay();
486     }
487 }
488 
handle()489 void MacroDelay::handle()
490 {
491     if (!started)
492         started = true;
493     if (!duration)
494     {
495         dprf("Expiring macro delay on turn: %d", you.num_turns);
496         stop_delay();
497     }
498     else
499         run_macro();
500 
501     // Macros may not use up turns, but unless we zero time_taken,
502     // main.cc will call world_reacts and increase turn count.
503     if (!you.turn_is_over && you.time_taken)
504         you.time_taken = 0;
505 }
506 
invalidated()507 bool MultidropDelay::invalidated()
508 {
509     // Throw away invalid items. XXX: what are they?
510     while (!items.empty()
511            // Don't look for gold in inventory
512            && items[0].slot != PROMPT_GOT_SPECIAL
513            && !you.inv[items[0].slot].defined())
514     {
515         items.erase(items.begin());
516     }
517 
518     if (items.empty())
519     {
520         // Ran out of things to drop.
521         you.turn_is_over = false;
522         you.time_taken = 0;
523         return true;
524     }
525     return false;
526 }
527 
tick()528 void MultidropDelay::tick()
529 {
530     if (!drop_item(items[0].slot, items[0].quantity))
531     {
532         you.turn_is_over = false;
533         you.time_taken = 0;
534     }
535     items.erase(items.begin());
536 }
537 
tick()538 void JewelleryOnDelay::tick()
539 {
540     // This is a 1-turn delay where the time cost is handled
541     // in finish().
542     // FIXME: get rid of this hack!
543     you.time_taken = 0;
544 }
545 
tick()546 void DropItemDelay::tick()
547 {
548     // This is a 1-turn delay where the time cost is handled
549     // in finish().
550     // FIXME: get rid of this hack!
551     you.time_taken = 0;
552 }
553 
handle()554 void Delay::handle()
555 {
556     if (!started)
557     {
558         started = true;
559         start();
560     }
561 
562     // First check cases where delay may no longer be valid:
563     // XXX: need to handle PasswallDelay when monster digs -- bwr
564     if (invalidated())
565     {
566         _pop_delay();
567         return;
568     }
569 
570     // Actually handle delay:
571     if (duration > 0)
572     {
573         dprf("Delay type: %s, duration: %d", name(), duration);
574         --duration;
575         tick();
576     }
577     else
578     {
579         finish();
580         you.wield_change = true;
581         _pop_delay();
582         print_stats();  // force redraw of the stats
583         update_screen();
584 #ifdef USE_TILE
585         tiles.update_tabs();
586 #endif
587         if (!you.turn_is_over)
588             you.time_taken = 0;
589     }
590 }
591 
handle_delay()592 void handle_delay()
593 {
594     if (!you_are_delayed())
595         return;
596 
597     shared_ptr<Delay> delay = current_delay();
598     delay->handle();
599 }
600 
finish()601 void JewelleryOnDelay::finish()
602 {
603     // Recheck -Tele here, since our condition may have changed since starting
604     // the amulet swap process.
605     // Just breaking here is okay because swapping jewellery is a one-turn
606     // action, so conceptually there is nothing to interrupt - in other words,
607     // this is equivalent to if the user took off the previous amulet and was
608     // affected by tele other before putting the -Tele amulet on as a separate
609     // action on the next turn.
610     // XXX: duplicates a check in invent.cc:check_warning_inscriptions()
611     if (!crawl_state.disables[DIS_CONFIRMATIONS]
612         && needs_notele_warning(jewellery, OPER_PUTON)
613         && item_ident(jewellery, ISFLAG_KNOW_TYPE))
614     {
615         string prompt = "Really put on ";
616         prompt += jewellery.name(DESC_INVENTORY);
617         prompt += " while about to teleport?";
618         if (!yesno(prompt.c_str(), false, 'n'))
619             return;
620     }
621 
622 #ifdef USE_SOUND
623     parse_sound(WEAR_JEWELLERY_SOUND);
624 #endif
625     puton_ring(jewellery, false, false, true);
626 }
627 
finish()628 void EquipOnDelay::finish()
629 {
630     const unsigned int old_talents = your_talents(false).size();
631     const bool is_amulet = equip.base_type == OBJ_JEWELLERY;
632     const equipment_type eq_slot = is_amulet ? EQ_AMULET :
633                                                get_armour_slot(equip);
634 
635 #ifdef USE_SOUND
636     if (!is_amulet)
637         parse_sound(EQUIP_ARMOUR_SOUND);
638 #endif
639     mprf("You finish putting on %s.", equip.name(DESC_YOUR).c_str());
640 
641     equip_item(eq_slot, equip.link);
642 
643     check_item_hint(equip, old_talents);
644 }
645 
invalidated()646 bool EquipOffDelay::invalidated()
647 {
648     return !equip.defined();
649 }
650 
finish()651 void EquipOffDelay::finish()
652 {
653     const bool is_amu = equip.base_type == OBJ_JEWELLERY;
654     const equipment_type slot = is_amu ? EQ_AMULET : get_armour_slot(equip);
655     ASSERT(you.equip[slot] == equip.link);
656 
657 #ifdef USE_SOUND
658     parse_sound(is_amu ? REMOVE_JEWELLERY_SOUND : DEQUIP_ARMOUR_SOUND);
659 #endif
660     mprf("You finish taking off %s.", equip.name(DESC_YOUR).c_str());
661     unequip_item(slot);
662 }
663 
finish()664 void MemoriseDelay::finish()
665 {
666 #ifdef USE_SOUND
667     parse_sound(MEMORISE_SPELL_SOUND);
668 #endif
669     mpr("You finish memorising.");
670     add_spell_to_memory(spell);
671     vehumet_accept_gift(spell);
672     quiver::on_actions_changed();
673 }
674 
finish()675 void PasswallDelay::finish()
676 {
677     mpr("You finish merging with the rock.");
678     // included in default force_more_message
679 
680     if (dest.x == 0 || dest.y == 0)
681         return;
682 
683     switch (env.grid(dest))
684     {
685     default:
686         if (!you.is_habitable(dest))
687         {
688             mpr("...yet there is something new on the other side. "
689                 "You quickly turn back.");
690             redraw_screen();
691             update_screen();
692             return;
693         }
694         break;
695 
696     case DNGN_CLOSED_DOOR:      // open the door
697     case DNGN_CLOSED_CLEAR_DOOR:
698     case DNGN_RUNED_DOOR:
699     case DNGN_RUNED_CLEAR_DOOR:
700         // Once opened, former runed doors become normal doors.
701         dgn_open_door(dest);
702         break;
703     }
704 
705     // Move any monsters out of the way.
706     if (monster* m = monster_at(dest))
707     {
708         // One square, a few squares, anywhere...
709         if (!m->shift() && !monster_blink(m, true))
710             monster_teleport(m, true, true);
711         // Might still fail.
712         if (monster_at(dest))
713         {
714             mpr("...and sense your way blocked. You quickly turn back.");
715             redraw_screen();
716             update_screen();
717             return;
718         }
719 
720         move_player_to_grid(dest, false);
721 
722         // Wake the monster if it's asleep.
723         if (m)
724             behaviour_event(m, ME_ALERT, &you);
725     }
726     else
727         move_player_to_grid(dest, false);
728 
729     // the last phase of the delay is a fake (0-time) turn, so world_reacts
730     // and player_reacts aren't triggered. Need to do a tiny bit of cleanup.
731     // This isn't very elegant, and perhaps a version of player_reacts that is
732     // triggered by changing location would be better (per Pleasingfungus),
733     // but player_reacts is very sensitive to order and can't be easily
734     // refactored in this way.
735     you.update_beholders();
736     you.update_fearmongers();
737 }
738 
finish()739 void ShaftSelfDelay::finish()
740 {
741     you.do_shaft_ability();
742 }
743 
finish()744 void DropItemDelay::finish()
745 {
746     // We're here if dropping the item required some action to be done
747     // first, like removing armour. At this point, it should be droppable
748     // immediately.
749 
750     // Make sure item still exists.
751     if (!item.defined())
752         return;
753 
754     if (!drop_item(item.link, 1))
755     {
756         you.turn_is_over = false;
757         you.time_taken = 0;
758     }
759 }
760 
finish()761 void AscendingStairsDelay::finish()
762 {
763     up_stairs();
764 }
765 
finish()766 void DescendingStairsDelay::finish()
767 {
768     down_stairs();
769 }
770 
finish()771 void ExsanguinateDelay::finish()
772 {
773     blood_spray(you.pos(), MONS_PLAYER, 10);
774     you.vampire_alive = false;
775     you.redraw_status_lights = true;
776     calc_hp(true);
777     mpr("You become bloodless.");
778     vampire_update_transformations();
779 }
780 
finish()781 void RevivifyDelay::finish()
782 {
783     you.vampire_alive = true;
784     you.redraw_status_lights = true;
785     mpr("You return to life.");
786     temp_mutate(MUT_FRAIL, "vampire revification");
787     vampire_update_transformations();
788 }
789 
run_macro(const char * macroname)790 void run_macro(const char *macroname)
791 {
792 #ifdef CLUA_BINDINGS
793     if (!clua)
794     {
795         mprf(MSGCH_DIAGNOSTICS, "Lua not initialised");
796         stop_delay();
797         return;
798     }
799 
800     shared_ptr<Delay> delay;
801     if (!macroname)
802     {
803         delay = current_delay();
804         ASSERT(delay->is_macro());
805     }
806     else
807         delay = start_delay<MacroDelay>();
808 
809     // If callbooleanfn returns false, that means the macro either exited
810     // normally by returning or by calling coroutine.yield(false). Either way,
811     // decrement the macro duration.
812     if (!clua.callbooleanfn(false, "c_macro", "s", macroname))
813     {
814         if (!clua.error.empty())
815         {
816             mprf(MSGCH_ERROR, "Lua error: %s", clua.error.c_str());
817             stop_delay();
818         }
819         else if (delay->duration > 0)
820             --delay->duration;
821     }
822 #else
823     mprf(MSGCH_ERROR, "CLua bindings not available on this build!");
824     UNUSED(macroname);
825     stop_delay();
826 #endif
827 }
828 
829 // Returns TRUE if the delay should be interrupted, MAYBE if the user function
830 // had no opinion on the matter, FALSE if the delay should not be interrupted.
_userdef_interrupt_activity(Delay * delay,activity_interrupt ai,const activity_interrupt_data & at)831 static maybe_bool _userdef_interrupt_activity(Delay* delay,
832                                               activity_interrupt ai,
833                                               const activity_interrupt_data &at)
834 {
835     lua_State *ls = clua.state();
836     if (!ls || ai == activity_interrupt::force)
837         return MB_TRUE;
838 
839     const char *interrupt_name = _activity_interrupt_name(ai);
840 
841     bool ran = clua.callfn("c_interrupt_activity", "1:ssA",
842                            delay->name(), interrupt_name, &at);
843     if (ran)
844     {
845         // If the function returned nil, we want to cease processing.
846         if (lua_isnil(ls, -1))
847         {
848             lua_pop(ls, 1);
849             return MB_FALSE;
850         }
851 
852         bool stopact = lua_toboolean(ls, -1);
853         lua_pop(ls, 1);
854         if (stopact)
855             return MB_TRUE;
856     }
857 
858     if (delay->is_macro() && clua.callbooleanfn(true, "c_interrupt_macro",
859                                                 "sA", interrupt_name, &at))
860     {
861         return MB_TRUE;
862     }
863     return MB_MAYBE;
864 }
865 
866 // Returns true if the activity should be interrupted, false otherwise.
_should_stop_activity(Delay * delay,activity_interrupt ai,const activity_interrupt_data & at)867 static bool _should_stop_activity(Delay* delay,
868                                   activity_interrupt ai,
869                                   const activity_interrupt_data &at)
870 {
871     switch (_userdef_interrupt_activity(delay, ai, at))
872     {
873     case MB_TRUE:
874         return true;
875     case MB_FALSE:
876         return false;
877     case MB_MAYBE:
878         break;
879     }
880 
881     // Don't interrupt player on monster's turn, they might wander off.
882     if (you.turn_is_over
883         && (at.context == SC_ALREADY_SEEN || at.context == SC_UNCHARM))
884     {
885         return false;
886     }
887 
888     // No monster will attack you inside a sanctuary,
889     // so presence of monsters won't matter.
890     if (ai == activity_interrupt::see_monster && is_sanctuary(you.pos()))
891         return false;
892 
893     auto curr = current_delay(); // Not necessarily what we were passed.
894 
895     if ((ai == activity_interrupt::see_monster
896          || ai == activity_interrupt::mimic)
897         && player_stair_delay())
898     {
899         return false;
900     }
901 
902     if (ai == activity_interrupt::full_hp || ai == activity_interrupt::full_mp
903         || ai == activity_interrupt::ancestor_hp)
904     {
905         if ((Options.rest_wait_both && curr->is_resting()
906              && !you.is_sufficiently_rested())
907             || (Options.rest_wait_ancestor && curr->is_resting()
908                 && !ancestor_full_hp()))
909         {
910             return false;
911         }
912     }
913 
914     // Don't interrupt feeding or butchering for monsters already in view.
915     if (ai == activity_interrupt::see_monster
916         && testbits(at.mons_data->flags, MF_WAS_IN_VIEW))
917     {
918         return false;
919     }
920 
921     return ai == activity_interrupt::force
922            || Options.activity_interrupts[delay->name()][static_cast<int>(ai)];
923 }
924 
_abyss_monster_creation_message(const monster * mon)925 static string _abyss_monster_creation_message(const monster* mon)
926 {
927     if (mon->type == MONS_DEATH_COB)
928     {
929         return coinflip() ? " appears in a burst of microwaves!"
930                           : " pops from nullspace!";
931     }
932 
933     // You may ask: "Why these weights?" So would I!
934     const vector<pair<string, int>> messages = {
935         { " appears in a shower of translocational energy.", 17 },
936         { " appears in a shower of sparks.", 34 },
937         { " materialises.", 45 },
938         { " emerges from chaos.", 13 },
939         { " emerges from the beyond.", 26 },
940         { make_stringf(" assembles %s!",
941                        mon->pronoun(PRONOUN_REFLEXIVE).c_str()), 33 },
942         { " erupts from nowhere.", 9 },
943         { " bursts from nowhere.", 18 },
944         { " is cast out of space.", 7 },
945         { " is cast out of reality.", 14 },
946         { " coalesces out of pure chaos.", 5 },
947         { " coalesces out of seething chaos.", 10 },
948         { " punctures the fabric of time!", 2 },
949         { " punctures the fabric of the universe.", 7 },
950         { make_stringf(" manifests%s!",
951                        silenced(you.pos()) ? "" : " with a bang"), 3 },
952 
953 
954     };
955 
956     return *random_choose_weighted(messages);
957 }
958 
_monster_warning(activity_interrupt ai,const activity_interrupt_data & at,shared_ptr<Delay> delay,vector<string> * msgs_buf=nullptr)959 static inline bool _monster_warning(activity_interrupt ai,
960                                     const activity_interrupt_data &at,
961                                     shared_ptr<Delay> delay,
962                                     vector<string>* msgs_buf = nullptr)
963 {
964     if (ai == activity_interrupt::sense_monster)
965     {
966         mprf(MSGCH_WARN, "You sense a monster nearby.");
967         return true;
968     }
969     if (ai != activity_interrupt::see_monster)
970         return false;
971     if (delay && !delay->is_run())
972         return false;
973     if (at.context != SC_NEWLY_SEEN && !delay)
974         return false;
975 
976     ASSERT(at.apt == ai_payload::monster);
977     monster* mon = at.mons_data;
978     ASSERT(mon);
979     if (!you.can_see(*mon))
980         return false;
981 
982     // Disable message for summons.
983     if (mon->is_summoned() && !delay)
984         return false;
985 
986     if (at.context == SC_ALREADY_SEEN || at.context == SC_UNCHARM)
987     {
988         // Only say "comes into view" if the monster wasn't in view
989         // during the previous turn.
990         if (testbits(mon->flags, MF_WAS_IN_VIEW) && delay)
991         {
992             mprf(MSGCH_WARN, "%s is too close now for your liking.",
993                  mon->name(DESC_THE).c_str());
994         }
995     }
996     else if (mon->seen_context == SC_JUST_SEEN)
997         return false;
998     else
999     {
1000         // XXX: This needs to be here to ensure correct messaging for
1001         // autoexplore, even though the correct place to process it is
1002         // seen_monster
1003         view_monster_equipment(mon);
1004 
1005         string text = getMiscString(mon->name(DESC_DBNAME) + " title");
1006         if (text.empty())
1007             text = mon->full_name(DESC_A);
1008         if (mon->type == MONS_PLAYER_GHOST)
1009         {
1010             text += make_stringf(" (%s)",
1011                                  short_ghost_description(mon).c_str());
1012         }
1013 
1014         if (at.context == SC_DOOR)
1015             text += " opens the door.";
1016         else if (at.context == SC_GATE)
1017             text += " opens the gate.";
1018         else if (at.context == SC_TELEPORT_IN)
1019             text += " appears from thin air!";
1020         else if (at.context == SC_LEAP_IN)
1021             text += " leaps into view!";
1022         else if (at.context == SC_FISH_SURFACES)
1023         {
1024             text += " bursts forth from the ";
1025             if (mons_primary_habitat(*mon) == HT_LAVA)
1026                 text += "lava";
1027             else if (mons_primary_habitat(*mon) == HT_WATER)
1028                 text += "water";
1029             else
1030                 text += "realm of bugdom";
1031             text += ".";
1032         }
1033         else if (at.context == SC_NONSWIMMER_SURFACES_FROM_DEEP)
1034             text += " emerges from the water.";
1035         else if (at.context == SC_UPSTAIRS)
1036             text += " comes up the stairs.";
1037         else if (at.context == SC_DOWNSTAIRS)
1038             text += " comes down the stairs.";
1039         else if (at.context == SC_ARCH)
1040             text += " comes through the gate.";
1041         else if (at.context == SC_ABYSS)
1042             text += _abyss_monster_creation_message(mon);
1043         else if (at.context == SC_THROWN_IN)
1044             text += " is thrown into view!";
1045         else
1046             text += " comes into view.";
1047 
1048         bool zin_id = false;
1049         string god_warning;
1050 
1051         if (have_passive(passive_t::warn_shapeshifter)
1052             && mon->is_shapeshifter()
1053             && !(mon->flags & MF_KNOWN_SHIFTER))
1054         {
1055             zin_id = true;
1056             mon->props["zin_id"] = true;
1057             discover_shifter(*mon);
1058             god_warning = uppercase_first(god_name(you.religion))
1059                           + " warns you: "
1060                           + uppercase_first(mon->pronoun(PRONOUN_SUBJECTIVE))
1061                           + " "
1062                           + conjugate_verb("are", mon->pronoun_plurality())
1063                           + " a foul ";
1064             if (mon->has_ench(ENCH_GLOWING_SHAPESHIFTER))
1065                 god_warning += "glowing ";
1066             god_warning += "shapeshifter.";
1067         }
1068 
1069         monster_info mi(mon);
1070 
1071         const string mweap = get_monster_equipment_desc(mi, DESC_IDENTIFIED,
1072                                                         DESC_NONE);
1073 
1074         if (!mweap.empty())
1075         {
1076             text += " " + uppercase_first(mon->pronoun(PRONOUN_SUBJECTIVE))
1077                 + " " + conjugate_verb("are", mi.pronoun_plurality())
1078                 + (mweap[0] != ' ' ? " " : "")
1079                 + mweap + ".";
1080         }
1081 
1082         if (msgs_buf)
1083             msgs_buf->push_back(text);
1084         else
1085         {
1086             mprf(MSGCH_MONSTER_WARNING, "%s", text.c_str());
1087             if (zin_id)
1088                 mprf(MSGCH_GOD, "%s", god_warning.c_str());
1089 #ifndef USE_TILE_LOCAL
1090             if (zin_id)
1091                 update_monster_pane();
1092 #endif
1093             if (player_under_penance(GOD_GOZAG)
1094                 && !mon->wont_attack()
1095                 && !mon->is_stationary()
1096                 && !mons_is_object(mon->type)
1097                 && !mons_is_tentacle_or_tentacle_segment(mon->type))
1098             {
1099                 if (coinflip()
1100                     && mon->get_experience_level() >=
1101                        random2(you.experience_level))
1102                 {
1103                     mprf(MSGCH_GOD, GOD_GOZAG, "Gozag incites %s against you.",
1104                          mon->name(DESC_THE).c_str());
1105                     gozag_incite(mon);
1106                 }
1107             }
1108         }
1109         if (you.has_mutation(MUT_SCREAM)
1110             && x_chance_in_y(you.get_mutation_level(MUT_SCREAM) * 6, 100))
1111         {
1112             yell(mon);
1113         }
1114         mons_set_just_seen(mon);
1115     }
1116 
1117     if (crawl_state.game_is_hints())
1118         hints_monster_seen(*mon);
1119 
1120     return true;
1121 }
1122 
1123 // Turns autopickup off if we ran into an invisible monster or saw a monster
1124 // turn invisible.
1125 // Turns autopickup on if we saw an invisible monster become visible or
1126 // killed an invisible monster.
autotoggle_autopickup(bool off)1127 void autotoggle_autopickup(bool off)
1128 {
1129     if (off)
1130     {
1131         if (Options.autopickup_on > 0)
1132         {
1133             Options.autopickup_on = -1;
1134             mprf(MSGCH_WARN,
1135                  "Deactivating autopickup; reactivate with <w>%s</w>.",
1136                  command_to_string(CMD_TOGGLE_AUTOPICKUP).c_str());
1137         }
1138         if (crawl_state.game_is_hints())
1139         {
1140             learned_something_new(HINT_INVISIBLE_DANGER);
1141             Hints.hints_seen_invisible = you.num_turns;
1142         }
1143     }
1144     else if (Options.autopickup_on < 0) // was turned off automatically
1145     {
1146         Options.autopickup_on = 1;
1147         mprf(MSGCH_WARN, "Reactivating autopickup.");
1148     }
1149 }
1150 
1151 // Returns true if any activity was stopped. Not reentrant.
interrupt_activity(activity_interrupt ai,const activity_interrupt_data & at,vector<string> * msgs_buf)1152 bool interrupt_activity(activity_interrupt ai,
1153                         const activity_interrupt_data &at,
1154                         vector<string>* msgs_buf)
1155 {
1156     if (interrupt_block::blocked())
1157         return false;
1158 
1159     const interrupt_block block_recursive_interrupts;
1160     if (ai == activity_interrupt::hit_monster
1161         || ai == activity_interrupt::monster_attacks)
1162     {
1163         const monster* mon = at.mons_data;
1164         if (mon && !mon->visible_to(&you) && !mon->submerged())
1165             autotoggle_autopickup(true);
1166     }
1167 
1168     if (crawl_state.is_repeating_cmd())
1169         return interrupt_cmd_repeat(ai, at);
1170 
1171     if (!you_are_delayed())
1172     {
1173         // Printing "[foo] comes into view." messages even when not
1174         // auto-exploring/travelling.
1175         if (ai == activity_interrupt::see_monster)
1176             return _monster_warning(ai, at, nullptr, msgs_buf);
1177         else
1178             return false;
1179     }
1180 
1181     const auto delay = current_delay();
1182 
1183     dprf("Activity interrupt: %s", _activity_interrupt_name(ai));
1184 
1185     // First try to stop the current delay.
1186     if (ai == activity_interrupt::full_hp && !you.running.notified_hp_full)
1187     {
1188         you.running.notified_hp_full = true;
1189         mpr("HP restored.");
1190     }
1191     else if (ai == activity_interrupt::full_mp && !you.running.notified_mp_full)
1192     {
1193         you.running.notified_mp_full = true;
1194         mpr("Magic restored.");
1195     }
1196     else if (ai == activity_interrupt::ancestor_hp
1197              && !you.running.notified_ancestor_hp_full)
1198     {
1199         // This interrupt only triggers when the ancestor is in LOS,
1200         // so this message does not leak information.
1201         you.running.notified_ancestor_hp_full = true;
1202         mpr("Ancestor HP restored.");
1203     }
1204 
1205     if (_should_stop_activity(delay.get(), ai, at))
1206     {
1207         _monster_warning(ai, at, delay, msgs_buf);
1208         // Teleport stops stair delays.
1209         stop_delay(ai == activity_interrupt::teleport);
1210         quiver::set_needs_redraw();
1211 
1212         return true;
1213     }
1214 
1215     // Check the other queued delays; the first delay that is interruptible
1216     // will kill itself and all subsequent delays. This is so that a travel
1217     // delay stacked behind a delay such as stair/autopickup will be killed
1218     // correctly by interrupts that the simple stair/autopickup delay ignores.
1219     for (int i = 1, size = you.delay_queue.size(); i < size; ++i)
1220     {
1221         if (_should_stop_activity(you.delay_queue[i].get(), ai, at))
1222         {
1223             quiver::set_needs_redraw();
1224             // Do we have a queued run delay? If we do, flush the delay queue
1225             // so that stop running Lua notifications happen.
1226             for (int j = i; j < size; ++j)
1227             {
1228                 if (you.delay_queue[j]->is_run())
1229                 {
1230                     _monster_warning(ai, at, you.delay_queue[j], msgs_buf);
1231                     _clear_pending_delays(i);
1232                     return true;
1233                 }
1234             }
1235 
1236             // Non-run queued delays can be discarded without any processing.
1237             you.delay_queue.erase(you.delay_queue.begin() + i,
1238                                   you.delay_queue.end());
1239             return true;
1240         }
1241     }
1242 
1243     return false;
1244 }
1245 
1246 // Must match the order of activity_interrupt.h!
1247 static const char *activity_interrupt_names[] =
1248 {
1249     "force", "keypress", "full_hp", "full_mp", "ancestor_hp", "message",
1250     "hp_loss", "stat", "monster", "monster_attack", "teleport", "hit_monster",
1251     "sense_monster", "mimic"
1252 };
1253 
_activity_interrupt_name(activity_interrupt ai)1254 static const char *_activity_interrupt_name(activity_interrupt ai)
1255 {
1256     COMPILE_CHECK(ARRAYSZ(activity_interrupt_names) == NUM_ACTIVITY_INTERRUPTS);
1257 
1258     if (ai == activity_interrupt::COUNT)
1259         return "";
1260 
1261     return activity_interrupt_names[static_cast<int>(ai)];
1262 }
1263 
get_activity_interrupt(const string & name)1264 activity_interrupt get_activity_interrupt(const string &name)
1265 {
1266     COMPILE_CHECK(ARRAYSZ(activity_interrupt_names) == NUM_ACTIVITY_INTERRUPTS);
1267 
1268     for (int i = 0; i < NUM_ACTIVITY_INTERRUPTS; ++i)
1269         if (name == activity_interrupt_names[i])
1270             return activity_interrupt(i);
1271 
1272     return activity_interrupt::COUNT;
1273 }
1274