1 /**
2  * @file
3  * @brief Functions to handle speaking monsters
4 **/
5 
6 #include "AppHdr.h"
7 
8 #include "mon-speak.h"
9 
10 #include <algorithm>
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 
15 #include "areas.h"
16 #include "branch.h"
17 #include "database.h"
18 #include "ghost.h"
19 #include "libutil.h"
20 #include "message.h"
21 #include "mon-death.h"
22 #include "monster.h"
23 #include "mon-util.h"
24 #include "religion.h"
25 #include "skills.h"
26 #include "state.h"
27 #include "stringutil.h"
28 #include "view.h"
29 
30 // Try the exact key lookup along with the entire prefix list.
31 // If that fails, start ignoring hostile/religion/branch/silence, in that order,
32 // first skipping hostile, then hostile *and* religion, then hostile, religion
33 // *and* branch, then finally all five.
__try_exact_string(const vector<string> & prefixes,const string & key,bool ignore_hostile=false,bool ignore_related=false,bool ignore_religion=false,bool ignore_branch=false,bool ignore_silenced=false)34 static string __try_exact_string(const vector<string> &prefixes,
35                                  const string &key,
36                                  bool ignore_hostile  = false,
37                                  bool ignore_related  = false,
38                                  bool ignore_religion = false,
39                                  bool ignore_branch   = false,
40                                  bool ignore_silenced = false)
41 {
42     bool hostile  = false;
43     bool related  = false;
44     bool religion = false;
45     bool branch   = false;
46     bool silenced = false;
47 
48     string prefix = "";
49     string msg = "";
50     const int size = prefixes.size();
51     for (int i = 0; i < size; i++)
52     {
53         if (prefixes[i] == "hostile")
54         {
55             if (ignore_hostile)
56                 continue;
57             hostile = true;
58         }
59         else if (prefixes[i] == "related")
60         {
61             if (ignore_related)
62                 continue;
63             related = true;
64         }
65         else if (prefixes[i] == "silenced")
66         {
67             if (ignore_silenced)
68                 continue;
69             silenced = true;
70         }
71         else if (prefixes[i] == "Beogh" || prefixes[i] == "good god"
72                  || prefixes[i] == "No God"
73                  || (str_to_god(prefixes[i]) != GOD_NO_GOD
74                      && prefixes[i] != "random"))
75         {
76             if (ignore_religion)
77                 continue;
78             religion = true;
79         }
80         else if (branch_by_abbrevname(prefixes[i]) != NUM_BRANCHES)
81         {
82             if (ignore_branch)
83                 continue;
84             branch = true;
85         }
86         prefix += prefixes[i];
87         prefix += " ";
88     }
89     msg = getSpeakString(prefix + key);
90 
91     if (msg.empty())
92     {
93         if (hostile) // skip hostile
94             msg = __try_exact_string(prefixes, key, true);
95         else if (related)
96         {
97             if (branch) // skip hostile and branch
98                 msg = __try_exact_string(prefixes, key, true, false, false, true);
99             else if (religion) // skip hostile and religion
100             {
101                 msg = __try_exact_string(prefixes, key, true, false, true,
102                                          ignore_branch);
103             }
104             else // skip hostile and related
105                 msg = __try_exact_string(prefixes, key, true, true);
106         }
107         else if (religion) // skip hostile, related and religion
108         {
109             if (branch && coinflip()) // skip hostile, related and branch
110                 msg = __try_exact_string(prefixes, key, true, true, false, true);
111             else // skip hostile, related and religion
112                 msg = __try_exact_string(prefixes, key, true, true, true);
113         }
114         else if (branch) // skip hostile, related, religion and branch
115             msg = __try_exact_string(prefixes, key, true, true, true, true);
116         // 50% use non-verbal monster speech,
117         // 50% try for more general silenced monster message instead
118         else if (silenced && coinflip()) // skip all
119             msg = __try_exact_string(prefixes, key, true, true, true, true, true);
120     }
121     return msg;
122 }
123 
_invalid_msg(const string & msg,bool no_player,bool no_foe,bool no_foe_name,bool no_god,bool unseen)124 static bool _invalid_msg(const string &msg, bool no_player, bool no_foe,
125                          bool no_foe_name, bool no_god, bool unseen)
126 {
127     if (no_player
128         && (msg.find("@player") != string::npos
129             || msg.find("@Player") != string::npos
130             || msg.find(":You") != string::npos))
131     {
132         return true;
133     }
134 
135     if (no_player)
136     {
137         for (const string &line : split_string("\n", msg))
138             if (starts_with(line, "You") || ends_with(line, "you."))
139                 return true;
140     }
141 
142     if (no_foe && (msg.find("@foe") != string::npos
143                    || msg.find("@Foe") != string::npos
144                    || msg.find("foe@") != string::npos
145                    || msg.find("@species") != string::npos))
146     {
147         return true;
148     }
149 
150     if (no_god && (msg.find("_god@") != string::npos
151                    || msg.find("@god_") != string::npos))
152     {
153         return true;
154     }
155 
156     if (no_foe_name && msg.find("@foe_name@") != string::npos)
157         return true;
158 
159     if (unseen && msg.find("VISUAL") != string::npos)
160         return true;
161 
162     return false;
163 }
164 
_try_exact_string(const vector<string> & prefixes,const string & key,bool no_player,bool no_foe,bool no_foe_name,bool no_god,bool unseen,bool ignore_hostile=false,bool ignore_related=false,bool ignore_religion=false,bool ignore_branch=false,bool ignore_silenced=false)165 static string _try_exact_string(const vector<string> &prefixes,
166                                 const string &key,
167                                 bool no_player, bool no_foe,
168                                 bool no_foe_name, bool no_god,
169                                 bool unseen,
170                                 bool ignore_hostile  = false,
171                                 bool ignore_related  = false,
172                                 bool ignore_religion = false,
173                                 bool ignore_branch   = false,
174                                 bool ignore_silenced = false)
175 {
176     string msg;
177     for (int tries = 0; tries < 10; tries++)
178     {
179         msg =
180             __try_exact_string(prefixes, key, ignore_hostile, ignore_related,
181                                ignore_religion, ignore_branch, ignore_silenced);
182 
183         // If the first message was non-empty and discarded then discard
184         // all subsequent empty messages, so as to not replace an
185         // invalid non-empty message with an empty one.
186         if (msg.empty())
187         {
188             if (tries == 0)
189                 return msg;
190             else
191             {
192                 tries--;
193                 continue;
194             }
195         }
196 
197         if (_invalid_msg(msg, no_player, no_foe, no_foe_name, no_god, unseen))
198         {
199             msg = "";
200             continue;
201         }
202         break;
203     }
204 
205     return msg;
206 }
207 
__get_speak_string(const vector<string> & prefixes,const string & key,bool no_player,bool no_foe,bool no_foe_name,bool no_god,bool unseen)208 static string __get_speak_string(const vector<string> &prefixes,
209                                  const string &key,
210                                  bool no_player, bool no_foe,
211                                  bool no_foe_name, bool no_god,
212                                  bool unseen)
213 {
214     string msg = _try_exact_string(prefixes, key, no_player, no_foe,
215                                    no_foe_name, no_god, unseen);
216 
217     if (!msg.empty())
218         return msg;
219 
220     // Combinations of prefixes by threes
221     const int size = prefixes.size();
222     string prefix = "";
223     if (size >= 3)
224     {
225         for (int i = 0; i < (size - 2); i++)
226             for (int j = i + 1; j < (size - 1); j++)
227                 for (int k = j + 1; k < size; k++)
228                 {
229                     prefix  = prefixes[i] + " ";
230                     prefix += prefixes[j] + " ";
231                     prefix += prefixes[k] + " ";
232 
233                     msg = getSpeakString("default " + prefix + key);
234 
235                     if (!msg.empty())
236                         return msg;
237                 }
238     }
239 
240     // Combinations of prefixes by twos
241     if (size >= 2)
242     {
243         for (int i = 0; i < (size - 1); i++)
244             for (int j = i + 1; j < size; j++)
245             {
246                 prefix  = prefixes[i] + " ";
247                 prefix += prefixes[j] + " ";
248 
249                 msg = getSpeakString("default " + prefix + key);
250 
251                 if (!msg.empty())
252                     return msg;
253             }
254     }
255 
256     // Prefixes singly
257     if (size >= 1)
258     {
259         for (int i = 0; i < size; i++)
260         {
261             prefix  = prefixes[i] + " ";
262 
263             msg = getSpeakString("default " + prefix + key);
264 
265             if (!msg.empty())
266                 return msg;
267         }
268     }
269 
270     // No prefixes
271     msg = getSpeakString("default " + key);
272 
273     return msg;
274 }
275 
_get_speak_string(const vector<string> & prefixes,string key,const monster * mons,bool no_player,bool no_foe,bool no_foe_name,bool no_god,bool unseen)276 static string _get_speak_string(const vector<string> &prefixes,
277                                 string key,
278                                 const monster* mons,
279                                 bool no_player, bool no_foe,
280                                 bool no_foe_name, bool no_god,
281                                 bool unseen)
282 {
283     int duration = 1;
284     if ((mons->flags & MF_BANISHED) && !player_in_branch(BRANCH_ABYSS))
285         key += " banished";
286     else if (mons->hit_points <= 0)
287     {
288         //separate death/permadeath lines for resurrection monsters
289         if (mons_is_mons_class(mons, MONS_NATASHA)
290                && !mons_felid_can_revive(mons)
291             || mons->type == MONS_BENNU
292                && !mons_bennu_can_revive(mons))
293         {
294             key += " permanently";
295         }
296         key += " killed";
297     }
298     else if (mons->is_summoned(&duration) && duration <= 0)
299         key += " unsummoned";
300 
301     string msg;
302     for (int tries = 0; tries < 10; tries++)
303     {
304         msg =
305             __get_speak_string(prefixes, key, no_player, no_foe,
306                                no_foe_name, no_god, unseen);
307 
308         // If the first message was non-empty and discarded then discard
309         // all subsequent empty messages, so as to not replace an
310         // invalid non-empty message with an empty one.
311         if (msg.empty())
312         {
313             if (tries == 0)
314                 return msg;
315             else
316             {
317                 tries--;
318                 continue;
319             }
320         }
321 
322         if (_invalid_msg(msg, no_player, no_foe, no_foe_name, no_god, unseen))
323         {
324             msg = "";
325             continue;
326         }
327 
328         break;
329     }
330 
331     return msg;
332 }
333 
334 /**
335  * Rolls a chance for a monster to speak, and calls mons_speaks as necessary.
336  *
337  * @param mons The monster in question.
338  */
maybe_mons_speaks(monster * mons)339 void maybe_mons_speaks(monster* mons)
340 {
341     // Very fast wandering/patrolling monsters might, in one monster turn,
342     // move into the player's LOS and then back out (or the player
343     // might move into their LOS and the monster move back out before
344     // the player's view has a chance to update) so prevent them
345     // from speaking.
346     if (mons->is_patrolling() || mons_is_wandering(*mons))
347         return;
348 
349     // per ef44f8a14, this seems to be handled elsewhere?
350     if (mons->attitude == ATT_NEUTRAL)
351         return;
352 
353     // too annoying for a permanent companion without more thought put into it
354     if (mons_is_hepliaklqana_ancestor(mons->type))
355         return;
356 
357     int chance = 21; // this is a very old number; no idea why it was chosen
358 
359     // allies stick around longer, so should probably have longer to say
360     // their piece; no need for them to chatter as much.
361     if (mons->wont_attack())
362         chance *= 15;
363     else if (!mons_is_unique(mons->type)
364              && testbits(mons->flags, MF_BAND_MEMBER))
365     {
366         // Band members are a lot less likely to speak, since there's
367         // a lot of them. Except for uniques.
368         chance *= 10;
369     }
370 
371     // Confused and fleeing monsters are more interesting.
372     if (mons_is_fleeing(*mons))
373         chance /= 2;
374     if (mons->has_ench(ENCH_CONFUSION))
375         chance /= 2;
376 
377     if ((mons_class_flag(mons->type, M_SPEAKS)
378                     || !mons->mname.empty())
379                 && one_chance_in(chance))
380     {
381         mons_speaks(mons);
382     }
383     else if ((mons->type == MONS_CRAZY_YIUF || mons->type == MONS_DONALD)
384         && one_chance_in(7))
385     {
386         // Yiuf gets an extra chance to speak!
387         // So does Donald.
388         mons_speaks(mons);
389     }
390     else if (get_mon_shape(*mons) >= MON_SHAPE_QUADRUPED)
391     {
392         // Non-humanoid-ish monsters have a low chance of speaking
393         // without the M_SPEAKS flag, to give the dungeon some
394         // atmosphere/flavour.
395         if (one_chance_in(chance * 4))
396             mons_speaks(mons);
397     }
398     // Okay then, don't speak.
399 }
400 
_get_foe(const monster & mon)401 static actor* _get_foe(const monster &mon)
402 {
403     if (!crawl_state.game_is_arena()
404         && mon.wont_attack()
405         && invalid_monster_index(mon.foe))
406     {
407         return &you;
408     }
409     return mon.get_foe();
410 }
411 
412 // Returns true if something is said.
mons_speaks(monster * mons)413 bool mons_speaks(monster* mons)
414 {
415     ASSERT(mons); // XXX: change to monster &mons
416     ASSERT(!invalid_monster_type(mons->type));
417 
418     // Natasha's death lines aren't physical speech.
419     if ((mons->asleep() || mons->cannot_act() || mons->flags & MF_EXPLODE_KILL)
420         && !(mons->type == MONS_NATASHA && !mons->alive()))
421     {
422         return false;
423     }
424 
425     // Monsters talk on death even if invisible/silenced/etc.
426     int duration = 1;
427     const bool force_speak = !mons->alive()
428         || (mons->flags & MF_BANISHED) && !player_in_branch(BRANCH_ABYSS)
429         || (mons->is_summoned(&duration) && duration <= 0)
430         || crawl_state.prev_cmd == CMD_LOOK_AROUND; // Wizard testing
431 
432     const bool unseen   = !you.can_see(*mons);
433     const bool confused = mons->confused();
434 
435     if (!force_speak)
436     {
437         // Invisible monster tries to remain unnoticed. Unless they're
438         // confused, since then they're too confused to realise they
439         // should stay silent, but only if the player can see them, so as
440         // to not have to deal with cases of speaking monsters which the
441         // player can't see.
442         if (unseen && !confused)
443             return false;
444 
445         // Silenced monsters only "speak" 1/3 as often as non-silenced,
446         // unless they're normally silent (S_SILENT).
447         if (mons->is_silenced() && mons_can_shout(mons->type)
448             && !one_chance_in(3))
449         {
450             return false;
451         }
452 
453         // Berserk monsters just want your hide.
454         if (mons->berserk_or_insane())
455             return false;
456 
457         // Rolling beetles shouldn't twitch antennae
458         if (mons->has_ench(ENCH_ROLLING))
459             return false;
460 
461         // Charmed monsters aren't too expressive.
462         if (mons->has_ench(ENCH_CHARM) && !one_chance_in(3))
463             return false;
464     }
465 
466     vector<string> prefixes;
467     if (mons->neutral())
468     {
469         if (!force_speak && coinflip()) // Neutrals speak half as often.
470             return false;
471 
472         prefixes.emplace_back("neutral");
473     }
474     else if (mons->friendly() && !crawl_state.game_is_arena())
475         prefixes.emplace_back("friendly");
476     else
477         prefixes.emplace_back("hostile");
478 
479     if (mons_is_fleeing(*mons))
480         prefixes.emplace_back("fleeing");
481 
482     bool silence = silenced(you.pos());
483     if (silenced(mons->pos()) || mons->has_ench(ENCH_MUTE))
484     {
485         silence = true;
486         prefixes.emplace_back("silenced");
487     }
488 
489     if (confused)
490         prefixes.emplace_back("confused");
491 
492     // Allows monster speech to be altered slightly on-the-fly.
493     if (mons->props.exists("speech_prefix"))
494         prefixes.push_back(mons->props["speech_prefix"].get_string());
495 
496     const actor*    foe  = _get_foe(*mons);
497     const monster* m_foe = foe ? foe->as_monster() : nullptr;
498 
499     if (!foe || foe->is_player() || mons->wont_attack())
500     {
501         // Animals only look at the current player form, smart monsters at the
502         // actual player genus.
503         if (is_player_same_genus(mons->type))
504             prefixes.emplace_back("related"); // maybe overkill for Beogh?
505     }
506     else
507     {
508         if (mons_genus(mons->mons_species()) ==
509             mons_genus(foe->mons_species()))
510         {
511             prefixes.emplace_back("related");
512         }
513     }
514 
515     const god_type god = foe               ? foe->deity() :
516                          crawl_state.game_is_arena() ? GOD_NO_GOD
517                                            : you.religion;
518 
519     // Add Beogh to list of prefixes for orcs (hostile and friendly) if you
520     // worship Beogh. (This assumes your being an orc, so might have odd
521     // results in wizard mode.) Don't count charmed or summoned orcs.
522     if (you_worship(GOD_BEOGH) && mons_genus(mons->type) == MONS_ORC)
523     {
524         if (!mons->has_ench(ENCH_CHARM) && !mons->is_summoned())
525         {
526             if (mons->god == GOD_BEOGH)
527                 prefixes.emplace_back("Beogh");
528             else
529                 prefixes.emplace_back("unbeliever");
530         }
531     }
532     else if (mons->type == MONS_PLAYER_GHOST)
533     {
534         // Use the *ghost's* religion, to get speech about its god. Only
535         // sometimes, though, so we can get skill-based messages as well.
536         if (coinflip())
537             prefixes.push_back(god_name(mons->ghost->religion));
538     }
539     else
540     {
541         // Include our current god's name, too. This means that uniques
542         // can have speech that is tailored to your specific god.
543         if (is_good_god(god) && coinflip())
544             prefixes.emplace_back("good god");
545         else
546             prefixes.push_back(god_name(you.religion));
547     }
548 
549     // Include our current branch, too. It can make speech vary by branch for
550     // uniques and other monsters! Specifically, Donald.
551     prefixes.emplace_back(branches[you.where_are_you].abbrevname);
552 
553     // Include a prefix for the orb run.
554     if (player_has_orb())
555         prefixes.emplace_back("orb");
556 
557 #ifdef DEBUG_MONSPEAK
558     {
559         string prefix;
560         const int size = prefixes.size();
561         for (int i = 0; i < size; i++)
562         {
563             prefix += prefixes[i];
564             prefix += " ";
565         }
566         dprf(DIAG_SPEECH, "monster speech lookup for %s: prefix = %s",
567              mons->name(DESC_PLAIN).c_str(), prefix.c_str());
568     }
569 #endif
570 
571     const bool no_foe      = (foe == nullptr);
572     const bool no_player   = crawl_state.game_is_arena()
573                              || (!mons->wont_attack()
574                                  && (!foe || !foe->is_player()));
575     const bool mon_foe     = (m_foe != nullptr);
576     const bool no_god      = no_foe || (mon_foe && foe->deity() == GOD_NO_GOD);
577     const bool named_foe   = !no_foe && (!mon_foe || (m_foe->is_named()
578                                 && m_foe->type != MONS_ROYAL_JELLY));
579     const bool no_foe_name = !named_foe
580                              || (mon_foe && (m_foe->flags & MF_NAME_MASK));
581 
582     string msg;
583 
584     // First, try its exact name.
585     if (mons->type == MONS_PLAYER_GHOST)
586     {
587         if (one_chance_in(5))
588         {
589             const ghost_demon &ghost = *(mons->ghost);
590             string ghost_skill  = skill_name(ghost.best_skill);
591             vector<string> with_skill = prefixes;
592             with_skill.push_back(ghost_skill);
593             msg = _get_speak_string(with_skill, "player ghost", mons,
594                                     no_player, no_foe, no_foe_name, no_god,
595                                     unseen);
596         }
597         if (msg.empty())
598         {
599             msg = _get_speak_string(prefixes, "player ghost", mons,
600                                     no_player, no_foe, no_foe_name, no_god,
601                                     unseen);
602         }
603     }
604     else if (mons->type == MONS_PANDEMONIUM_LORD)
605     {
606         // Pandemonium demons have randomly generated names, so use
607         // "pandemonium lord" instead.
608         msg = _get_speak_string(prefixes, "pandemonium lord", mons,
609                                 no_player, no_foe, no_foe_name, no_god,
610                                 unseen);
611     }
612     else
613     {
614         if (msg.empty() && mons->props.exists("dbname"))
615         {
616             msg = _get_speak_string(prefixes,
617                                      mons->props["dbname"].get_string(),
618                                      mons, no_player, no_foe, no_foe_name,
619                                      no_god, unseen);
620 
621             if (msg.empty())
622             {
623                 // Try again without the prefixes if the key is empty. Vaults
624                 // *really* want monsters to use the key specified, rather than
625                 // the key with prefixes.
626                 vector<string> faux_prefixes;
627                 msg = _get_speak_string(faux_prefixes,
628                                      mons->props["dbname"].get_string(),
629                                      mons, no_player, no_foe, no_foe_name,
630                                      no_god, unseen);
631             }
632         }
633 
634         // If the monster was originally a unique which has been polymorphed
635         // into a non-unique, is its current monster type capable of using its
636         // old speech?
637         if (!mons->mname.empty() && mons->can_speak() && msg.empty())
638         {
639             msg = _get_speak_string(prefixes, mons->name(DESC_PLAIN),
640                                     mons, no_player, no_foe, no_foe_name,
641                                     no_god, unseen);
642         }
643 
644         if (msg.empty())
645         {
646             msg = _get_speak_string(prefixes, mons->base_name(DESC_PLAIN),
647                                     mons, no_player, no_foe, no_foe_name,
648                                     no_god, unseen);
649         }
650     }
651 
652     // The exact name brought no results, try monster genus.
653     if ((msg.empty() || msg == "__NEXT")
654         && mons_genus(mons->type) != mons->type)
655     {
656         msg = _get_speak_string(prefixes,
657                        mons_type_name(mons_genus(mons->type), DESC_PLAIN),
658                        mons, no_player, no_foe, no_foe_name, no_god,
659                        unseen);
660     }
661 
662     // __NONE means to be silent, and __NEXT means to try the next,
663     // less exact method of describing the monster to find a speech
664     // string.
665 
666     if (msg == "__NONE")
667     {
668 #ifdef DEBUG_MONSPEAK
669         dprf(DIAG_SPEECH, "result: \"__NONE\"!");
670 #endif
671         return false;
672     }
673 
674     // Now that we're not dealing with a specific monster name, include
675     // whether or not it can move in the prefix.
676     if (mons->is_stationary())
677         prefixes.insert(prefixes.begin(), "stationary");
678 
679     // Names for the exact monster name and its genus have failed,
680     // so try the monster's glyph/symbol.
681     if (msg.empty() || msg == "__NEXT")
682     {
683         string key = "'";
684 
685         // Database keys are case-insensitve.
686         if (isaupper(mons_base_char(mons->type)))
687             key += "cap-";
688 
689         key += mons_base_char(mons->type);
690         key += "'";
691         msg = _get_speak_string(prefixes, key, mons, no_player, no_foe,
692                                 no_foe_name, no_god, unseen);
693     }
694 
695     if (msg == "__NONE")
696     {
697 #ifdef DEBUG_MONSPEAK
698         dprf(DIAG_SPEECH, "result: \"__NONE\"!");
699 #endif
700         return false;
701     }
702 
703     if (mons_intel(*mons) < I_HUMAN)
704         prefixes.insert(prefixes.begin(), "stupid");
705 
706     const mon_body_shape shape = get_mon_shape(*mons);
707     if (msg.empty() || msg == "__NEXT")
708     {
709         msg = _get_speak_string(prefixes, get_mon_shape_str(shape), mons,
710                                 no_player, no_foe, no_foe_name, no_god,
711                                 unseen);
712     }
713 
714     if (msg == "__NONE")
715     {
716 #ifdef DEBUG_MONSPEAK
717         dprf(DIAG_SPEECH, "result: \"__NONE\"!");
718 #endif
719         return false;
720     }
721 
722     // If we failed to get a message with a partial/hybrid humanoid, try moving
723     // closer to plain humanoid.
724     if ((msg.empty() || msg == "__NEXT") && mon_shape_is_humanoid(shape)
725         && shape != MON_SHAPE_HUMANOID)
726     {
727         // If a humanoid monster has both wings and a tail, try removing
728         // one and then the other to see if we get any results.
729         if (shape == MON_SHAPE_HUMANOID_WINGED_TAILED)
730         {
731             msg = _get_speak_string(prefixes,
732                                     get_mon_shape_str(MON_SHAPE_HUMANOID_TAILED),
733                                     mons, no_player, no_foe, no_foe_name,
734                                     no_god, unseen);
735 
736             // Only be silent if both tailed and winged return __NONE.
737             if (msg.empty() || msg == "__NONE" || msg == "__NEXT")
738             {
739                 string msg2;
740                 msg2 = _get_speak_string(prefixes,
741                                          get_mon_shape_str(MON_SHAPE_HUMANOID_WINGED),
742                                          mons, no_player, no_foe,
743                                          no_foe_name, no_god, unseen);
744 
745                 if (msg == "__NONE" && msg2 == "__NONE")
746                 {
747 #ifdef DEBUG_MONSPEAK
748                     dprf(DIAG_SPEECH, "result: \"__NONE\"!");
749 #endif
750                     return false;
751                 }
752 
753                 if (msg2 == "__NONE")
754                     msg2 = "";
755 
756                 msg = msg2;
757             }
758         }
759 
760         if (msg.empty() || msg == "__NONE" || msg == "__NEXT")
761         {
762             msg = _get_speak_string(prefixes,
763                                     get_mon_shape_str(MON_SHAPE_HUMANOID),
764                                     mons, no_player, no_foe, no_foe_name,
765                                     no_god, unseen);
766         }
767     }
768     if (msg.empty() || msg == "__NONE")
769     {
770 #ifdef DEBUG_MONSPEAK
771         dprf(DIAG_SPEECH, "final result: %s!",
772              (msg.empty() ? "empty" : "\"__NONE\""));
773 #endif
774         return false;
775     }
776 
777     if (msg == "__NEXT")
778     {
779         msg::streams(MSGCH_DIAGNOSTICS)
780             << "__NEXT used by shape-based speech string for monster '"
781             << mons->name(DESC_PLAIN) << "'" << endl;
782         return false;
783     }
784 
785     return mons_speaks_msg(mons, msg, MSGCH_TALK, silence);
786 }
787 
invalid_msg(const monster & mon,string msg)788 bool invalid_msg(const monster &mon, string msg)
789 {
790     const actor*    foe    = _get_foe(mon);
791     const monster* m_foe   = foe ? foe->as_monster() : nullptr;
792     // TODO: dedup with mons_speaks()
793     const bool no_foe      = (foe == nullptr);
794     const bool no_player   = crawl_state.game_is_arena()
795                              || (!mon.wont_attack()
796                                  && (!foe || !foe->is_player()));
797     const bool mon_foe     = (m_foe != nullptr);
798     const bool no_god      = no_foe || (mon_foe && foe->deity() == GOD_NO_GOD);
799     const bool named_foe   = !no_foe && (!mon_foe || (m_foe->is_named()
800                                 && m_foe->type != MONS_ROYAL_JELLY));
801     const bool no_foe_name = !named_foe
802                              || (mon_foe && (m_foe->flags & MF_NAME_MASK));
803     const bool unseen = !you.can_see(mon);
804     return _invalid_msg(msg, no_player, no_foe, no_foe_name, no_god, unseen);
805 
806 }
807 
mons_speaks_msg(monster * mons,const string & msg,const msg_channel_type def_chan,bool silence)808 bool mons_speaks_msg(monster* mons, const string &msg,
809                      const msg_channel_type def_chan, bool silence)
810 {
811     if (!you.see_cell(mons->pos()))
812         return false;
813 
814     mon_acting mact(mons);
815 
816     // We have a speech string, now parse and act on it.
817     const string _msg = do_mon_str_replacements(msg, *mons);
818     const vector<string> lines = split_string("\n", _msg);
819 
820     bool noticed = false;       // Any messages actually printed?
821 
822     if (mons->has_ench(ENCH_MUTE))
823         silence = true;
824 
825     for (string line : lines)
826     {
827         // This function is a little bit of a problem for the message
828         // channels since some of the messages it generates are "fake"
829         // warning to scare the player. In order to accommodate this
830         // intent, we're falsely categorizing various things in the
831         // function as spells and danger warning... everything else
832         // just goes into the talk channel -- bwr
833         // [jpeg] Added MSGCH_TALK_VISUAL for silent "chatter".
834         msg_channel_type msg_type = def_chan;
835 
836         if (strip_channel_prefix(line, msg_type, silence))
837         {
838             if (msg_type == MSGCH_MONSTER_SPELL && mons->friendly())
839                 msg_type = MSGCH_FRIEND_SPELL;
840             if (msg_type == MSGCH_MONSTER_ENCHANT && mons->friendly())
841                 msg_type = MSGCH_FRIEND_ENCHANT;
842             if (line.empty())
843                 continue;
844         }
845 
846         const bool old_noticed = noticed;
847         noticed = true;         // Only one case is different.
848 
849         // Except for VISUAL, none of the above influence these.
850         if (msg_type == MSGCH_TALK_VISUAL)
851             silence = false;
852 
853         if (msg_type == MSGCH_TALK_VISUAL && !you.can_see(*mons))
854             noticed = old_noticed;
855         else
856         {
857             if (you.can_see(*mons))
858                 handle_seen_interrupt(mons);
859             mprf(msg_type, "%s", line.c_str());
860         }
861     }
862     return noticed;
863 }
864