I found my previous change to block all messages passed through MSGCH_TALK when silenced was too restrictive, so I've added another channel MSGCH_TALK_VISUAL and adapted the monster speech files accordingly. For example, imps can now also "talk" when silenced, but only the visual stuff will actually be output. (This automatically takes care of lowering the output likelihood.) And no, this doesn't hurt any, as visual talk also won't interrupt travel or resting.
And I added a how-to file on monster speech, which was the main reason for my silence during the last couple of hours. It's not that the database system is that complicated but it surely can't hurt to give players who want to add something an idea of what is possible and how to go about it.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2108 c06c8d41-db1a-0410-9941-cceddc491573
AIIVH43Z5X3GTPFY4FXQRZPG6Y7QPH2KJ47VM2Q43PCGGD5MTMOAC KH5DN75GPQGMSUV5VTNFSXV4G3Q43O4R4M2BADFSYEEQYUQFCWMAC BFZZ7DFLZM4WNHQOKWDJENZOLMXH3UPHZ437BMISYJ3VSO2Y57WQC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC J6APXOT4QOGQFONWB7G546VTVF6QG42HVOROMHF7YBDJPR4K26OAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC PFEJ4LMDNEKLMGRCMWQ7EIRVU4JMYGICI4G7X4WVWOROVXQCBZ7QC 3QLM46S44Z7GDLWPH3VHBMW2RSWZAOLGJMG2BDKNGUOZIM4IX6WAC Y56C5OMUQ5XF2G6DKDV4R5MED44UOIUPTBBQVWQBUHYIXYA5MOZAC BMHUBADDGIOZRVN4P3O5QKIDUYD4RFWBS7MP5X6LZWAYHUBRVD2QC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC if (mons_shouts(monster->type) == S_SILENT)msg::streams(MSGCH_TALK) << msg << std::endl;elsemsg::streams(MSGCH_SOUND) << msg << std::endl;
if (pos != std::string::npos){param = msg.substr(0, pos);msg = msg.substr(pos + 1);}if (mons_shouts(monster->type) == S_SILENT || param == "VISUAL")channel = MSGCH_TALK_VISUAL;else if (param == "SOUND")channel = MSGCH_SOUND;msg::streams(channel) << msg << std::endl;
if (line == "__YOU_RESIST"){canned_msg( MSG_YOU_RESIST );continue;}else if (line == "__NOTHING_HAPPENS"){canned_msg( MSG_NOTHING_HAPPENS );continue;}else if (line == "__MORE"){more();continue;}
// except for VISUAL none of the above influence theseif (line == "__YOU_RESIST" && (!silence || param == "VISUAL")){canned_msg( MSG_YOU_RESIST );continue;}else if (line == "__NOTHING_HAPPENS" && (!silence || param == "VISUAL")){canned_msg( MSG_NOTHING_HAPPENS );continue;}else if (line == "__MORE" && (!silence || param == "VISUAL")){more();continue;}
################################################################### Library of randomized word/phrase substitutions. (The keys will# have to be changed in the unlikely event that monsters are ever# given names like "yells" or "begs".)##################################################################%%%%
############################################################# As of Stone Soup 0.3 the previously hardcoded monster# speech has been outsourced. This makes changing existing# messages, and adding new ones really easy.## speak.txt contains the messages of monsters that "talk"# to the player, or at least the biggest part there-of.## For an explanation of how to read shout.txt and speak.txt# and how to add new messages, see monster_speech.txt in the# docs directory######################################################################################################################### Library of randomized word/phrase substitutions. (The keys# will have to be changed in the unlikely event that# monsters are ever given names like "yells" or "begs".)############################################################%%%%
####################################################################### Library of speeches for types of monsters, like priests, wizards,# guards and so on.######################################################################
############################################################# Library of speeches for types of monsters, like priests,# wizards, guards and so on.############################################################
####################################################################### Speech strings by monster symbol######################################################################%%%%
########################################## Speech strings by monster symbol#########################################%%%%
##################################################################### Player ghost phrases. Ghosts with different classes can be given
%%%%##################################################################### Player ghost phrases. Ghosts with different classes can be given
####################################################################### Unique monsters######################################################################%%%%
######################################## Unique monsters#######################################%%%%
####################################################################### Specific non-unique monsters######################################################################%%%%
########################################### Specific non-unique monsters##########################################%%%%
############################################################# As of Stone Soup 0.3 the previously hardcoded monster# speech has been outsourced. This makes changing existing# messages, and adding new ones really easy.## shout.txt holds the utterances (and visual equivalents) of# monsters that notice you.## For an explanation of how to read shout.txt and speak.txt# and how to add new messages, see monster_speech.txt in the# docs directory.############################################################
# handle_monster_shouts() in view.cc detects buggy behavior, so# showing this line would itself be a bug.You hear doubly buggy behavior!
# handle_monster_shouts() in view.cc detects buggy behavior,# so showing this line would itself be a bug.SOUND:You hear doubly buggy behavior!
##################################################################### Player ghost shouts. Potentially different ones for each class,# though currently they all just copy the default player ghost.####################################################################
############################################################# Player ghost shouts. Potentially different ones for each# class, though currently they all just copy the default# player ghost.############################################################
As of Stone Soup 0.3 the previously hard-coded monsterspeech has been outsourced into shout.txt and speak.txt byMatthew Cline. This makes changing existing messages, oradding new ones really easy. This file will hopefully helpyou in this endeavour.shout.txt handles message output for monsters noticing you.speak.txt handles messages for monsters communicating.If you take a look through the two files, you'll see thatall entries have basically the same structure. Let's have alook at an xample:################ Friendly imps###############%%%%# Friendly imps are very common so they speak very rarelyfriendly '5'w:9__NONEw:1@_friendly_imp_@%%%%Now let's have a look at these in more detail:# Friendly impsA '#' sign at the beginning of line means this line willbe ignored, so it's used as a comment.%%%%The four percentage signs mark beginning and end of adatabase entry. If you forget to place these, buggymonster speech will result.friendly '5'The first non-comment, non-clear line is interpreted asthe key of an entry. Most keys are hardcoded but there'splace for user defined ones as well. In this case, the keyis "friendly '5'".'5' refers to the monster glyph, so the speech will not beentirely restricted to imps, though they are by far themost common ones.On the whole there are three ways the game tries to lookfor keys in the database. First the actual monster name isused, then the monster glyph (with prefix "cap-" forcapital letters), then a a group description (such asinsect or humanoid) defined by the monster's body shape.The latter is entirely hardcoded, though."friendly" is one of a couple of allowed prefixes,distinguishing the speech from "hostile" (default).These prefixes are optional and tested in the followingorder:default friendly/hostile fleeing silenced confused monsterFirst the database is searched for the whole prefixstring, then reading from left to right the combinationsare tested, beginning at three prefixes and ending atnone, at which time the prefix "default" is used instead.For the last round (shape comparison, e.g. winged humanoidetc.) a prefix on intelligence gets added. If in this lastround still nothing has been found, the monster stayssilent.w:9After a clear line the actual talk begins. You can skewthe probability of a given message with the weight ('w')tag. A message will be chosen with a probability of itsweight (defaults to 10 if none set) out of the sum ofweights for this entry. In this case, nine times out often a friendly imp will stay silent.__NONEAside from "__NONE" there are a few other hardcodedmarkers:__NONE : no message__NEXT : try the next combination of attributes__MORE : enforce a "-- More --" prompt__YOU_RESIST : "You resist."__NOTHING_HAPPENS : "Nothing appears to happen."In addition, some more are defined in speak.txt andshout.txt, such as __RESIST_OR_NOTHING, __SHOUT, andothers.@_friendly_imp_@Other variables can be defined in the form of @variable@.The "@_friendly_imp_@" above is key to another entry inthe database entitled "_friendly_imp_" (without those '@'signs) that actually has imps talking. Their speechincludes messages such as the following.VISUAL:@The_monster@ grins impishly at you.VISUAL:@The_monster@ picks up some beetles from the @surface@ and offers them to you.Again, there have to be clear lines between the differentmessages. If messages are placed directly one after anotherthey will be printed as a block. This can be useful, e.g.for outputting first a "spell" and then it's (fake) result.Monster speech can be greatly customized by the use ofseveral variables. This example already includes a few.VISUAL:This optional parameter at the beginning of a stringdecides which message channel a string will be passedthrough. The list of allowed tags is as follows:TALK : MSGCH_TALK (Default value.)DANGER : MSGCH_DANGERENCHANT : MSGCH_ENCHANTPLAIN : MSGCH_PLAINSOUND : MSGCH_SOUNDSPELL : MSGCH_MONSTER_SPELLVISUAL : MSGCH_TALK_VISUALWARN : MSGCH_WARNNote that MSGCH_SOUND and MSGCH_TALK get filtered outwhen you are silenced. For similar reasons monster speechof channel SPELL is muted under silence, along withENCHANT and WARN, both of which currently only occur incombination with SPELL. To allow for silent spells alongwith fake warnings and enchantments, you can combine thesewith VISUAL and enforce output even when silenced.VISUAL SPELL : MSGCH_SPELLVISUAL WARN : MSGCH_WARNVISUAL ENCHANT : MSGCH_ENCHANTNote, though, that these hardly ever take effect asusually the "silenced humanoid" types take precedence.Only if no message for the silenced monster type is foundthese special VISUAL cases will apply.For shouts the default is also MSGCH_TALK which ischanged to MSGCH_TALK_VISUAL for monsters that don'tspeak, and manually set to MSGCH_SOUND for all thosevariants of "You hear a shout!"@The_monster@, @surface@Like with @_friendly_imp_@ above, variables have beendefined to allow for greater flexibility. When the speechcode encounters an '@' sign it will first search thedatabase for a variable of that name and execute thenecessary replacement. Note that recursive replacement ofone variable with another is possible, so try to avoidloops. The remaining variables it was unable to find inthe database are hardcoded and will be replaced beforeoutput. If you add a new variable make sure to also add adatabase entry for it (without those '@' marks around!);otherwise it won't get replaced and just look weird.A variable that you will see all over the place is@The_monster@ which is hardcoded and will be replaced withthe monster's name. This is particularly useful for groupsof monsters that share the same speech pattern. Anothervariable you can see in this example is @surface@ whichwill be replaced by whatever the monster is standing on.The following variables are hardcoded:@the_monster@ : replaced with definite article plusmonster name for non-unique monsters@Monster@ : as above, but capitalized@the_monster@ : replaced with monster name@The_monster@ : replaced with capitalized monster name@a_monster@ : replaced with indefinite article plusmonster name, if several can exist@A_monster@ : as above, but capitalized@Monster@ : replaced with plain monster name@monster@ : es above, but capitalizedFor friendly monsters an additional "your"/"Your" isplaced before the monster name, respecting capitalizationand grammar (only for the_xxx).As an alternative there's also @the_something@,@The_something@, @a_something@, @A_something@, @something@and @Something@, all of which behave like the correspondingmonster definitions above but get replaced by "something"and "Something", respectively, should the monster beinvisible and the player be unable to see invisible.But wait, there's more!@player_name@ : replaced by player name@surface@ : replaced with whatever the monster stands on@feature@ : replaced with the monster's square's featuredescription@pronoun@ : replaced be it, she, he as appropriate@Pronoun@ : replaced be It, She, He, as appropriate@possessive@ : replaced by its, her, his as appropriate@Possessive@ : replaced by Its, Her, His, as appropriate@imp_taunt@ : replaced by hardcoded imp type insults@demon_taunt@ : replaced by hardcoded demon type insultsAlso, @says@ will get replaced with a synonym of 'say' thatfits a monster's (hardcoded) speech pattern and noise level.Pre-defined variables in the database include _high_priest_,_mercenary_guard_, _wizard_, _hostile_adventurer_,_friendly_imp_, _hostile_imp_, _tormentor_. There are also afew synonyms defined at the beginning of speak.txt such asfor @ATTACK@, @pointless@, @shouts@, @wails@, @yells@ andothers.