zelgadis. Currently, shout.txt and speak.txt share in with the .des files in /dat. That should be changed, but I've no idea how to do this.
Also implementing a bug fix by ennewalker (1787428).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2052 c06c8d41-db1a-0410-9941-cceddc491573
J6APXOT4QOGQFONWB7G546VTVF6QG42HVOROMHF7YBDJPR4K26OAC FDODUDJBCF5LLARJNKBS65WDCHWE3TJY57X6LQDDMGRXMFFKG6WQC VORPJHCEZKAOM3NHZSGHS2TT5X5AVR4WZFTA4PPZHS2NF5O6K2OQC 6STQOVN7PAYN5Y7PISP7PFCV4SDZUMHVOI7DQGUN5GM2SLLA5CPAC HSRRNAU5UAYC6B6IQWGJPFROMZBTJICPCH6DJVZDHDTAGOQ6IOYAC RCPQNIRPR3NQXEMVLBAQW6657UJFIP43N54UJVEZHJH22OH4UQIQC 54QO7QZXN6HFLXHLBLZK3QVXMX3JWBFS4WKS4WWCYVBK3KUZPQFAC I7QLYOTE6DLQZM7YWUWYLKHRJRB2A3STQ42ALSRGQICEWKD2QTEQC RGY2525RQH7SSGM6ZVI7CZL4WMNFZK2WRABOSIWRKQYYOU2RWN4QC BW3XFNOS6LDAQLHOZ6RXARCMKCY5JVLVDSXDSSAX4DSYM3FANQBAC UWMN4HLG6YA2YFQEVIVMDISD6APKEPIZXMMPMNUYCBQDSAUYSXPQC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC PFEJ4LMDNEKLMGRCMWQ7EIRVU4JMYGICI4G7X4WVWOROVXQCBZ7QC WT66JDIRTLLP37SHTV4GI3V64JFJ4D25LNRLGCHFG6CLEFKJ3QGQC UQFNR6PCRYPSUWMFF7KHITOVE4DZJ4CEAHFSXO7NG6GYZRF5JKUAC 3QLM46S44Z7GDLWPH3VHBMW2RSWZAOLGJMG2BDKNGUOZIM4IX6WAC 4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC E5DMZFW6WCFAKTKKOQPYTQXZ2CGLWMVH64LRXDUI2UIG4VYUHIVQC RSIUBEQUGNU4LO6KH4PKVROWQS33DAKSY4XFVGN7T3CEKSXABCSAC X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC OP6CTAKWCAU64JXQ3USQYR5E5IFHQHNCACII5UMVRXUTZXJQOAZAC 2XG4UYEUFFZV4ARZJXQ36KQBK3XEAY77KEJOJ4X27NP5IBSF27YQC D4MYPHZGUOL7HPS53DUUM4QSPIR5W3227DENDB4OBNDVQ4BU5VDAC DYBB7LISQQKT734KRIQZCO67OGDQWLZ2KSTDZUY4BZFCCOIDTUWAC MTM3ZU5KREJPXEMV3VVPDYWA5JZJISUBYDVEWCPBWNCKJF67CHWAC 7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC 5V47S4NNTHWTSAHV3YLO2VGH7JTUIYJ3GBPDN5ZM4UQALT2ZEXDQC 5XSXMOBGXFLTIQE6WDXWWFVDOTUPZSIQ2FWT3YI5QMVU6D76IUYQC DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC BNTPYSO6ECZ76CHHLDP3ASSPDSEUH4Y3E3LETKNXVWAWJRFL3YEQC LW4N5EHKL776DURXZMAM6JEW3JPWWX5BSNP7TCZHTLCDOQTTGFCAC QDWDUURSNLMT6AXNNJ3DEQCWAKCAIHV6MP5F7QGIBGXOG2BI2NPQC 7KWDC7XFNMBLSUO2HISIROBINZBX5T67LJEEXTAORXW2YZ7VWFGAC DODCHP2S4I6VZKQAVXX6D76OPNFI2YWZ4XH3HZTMAJZXA2RJ3XRQC CQ24AVAI6SW3AHTIDMLPSTRRBEU6FHRF5I5FD6G5QIYE6PO4BQMQC UZ6N6HOUPGVSPC5NQROEEDWMEGJA5XUWUY2AKH5QG65AZ25PVXDAC TJRYL3NXPW5IUGEV3YOC7JYWEXCZDBFPLT4AUG4P227WVKVB72ZAC WLX2RQMMOMP2PYPAGJRM4VFD2WTLJTOAZZPPY3MV76FU2EGEJ54QC DTO3EUKWHZ5RJNGNCFYXSOVTIPVXPP637F2W7WFGYKJ7JK7VNKNQC 3C2VE43SHCSBY4LTRTFYFLIPRWFUN6DXU6D34QVWDQTSNRBUFG7AC Y56C5OMUQ5XF2G6DKDV4R5MED44UOIUPTBBQVWQBUHYIXYA5MOZAC KR655YT3I3U5DMN5NS3FPUGMDNT4BI56K3SFF2FNJ77C45NFKL5AC 5SFYYTKXTWLSBXB4PUB6G3E47W6DNROQNDLN3UJZQ4FN7ML3MADQC X2FMEN4E345XD26Z2X7JMJ7VGHOGCGIELMHQRE2ITLVNQACP3NOQC TZ643KHSE5CUPXFSQ7VYVOCM5MTQ7F4SENEYQX2RNFHGHLQVS3RQC M47QBURKKRV2JFK6U7GQNVWK7RUTBVPBJ5FHURC55SKQSXAUFSBAC if (you.turn_is_over&& mons_shouts(monster->type) != S_SILENT&& random2(30) >= you.skills[SK_STEALTH])
if (!force&& (!you.turn_is_over || random2(30) < you.skills[SK_STEALTH]))return;// Get it once, since monster might be S_RANDOM, in which case// mons_shouts() will return a different value every time.shout_type type = mons_shouts(monster->type);// Silent monsters can give noiseless "visual shouts" if the// player can see them, in which case silence isn't checked for.if (mons_friendly(monster)|| (type == S_SILENT && !player_monster_visible(monster))|| (type != S_SILENT && (silenced(you.x_pos, you.y_pos)|| silenced(monster->x, monster->y))))return;int noise_level = 8;std::string default_msg_key;switch (type){case NUM_SHOUTS:case S_RANDOM:default_msg_key = "__BUGGY";break;case S_SILENT:default_msg_key = "";noise_level = 0;break;case S_SHOUT:default_msg_key = "__SHOUT";break;case S_BARK:default_msg_key = "__BARK";break;case S_SHOUT2:default_msg_key = "__TWO_SHOUTS";noise_level = 12;break;case S_ROAR:default_msg_key = "__ROAR";noise_level = 12;break;case S_SCREAM:default_msg_key = "__SCREAM";break;case S_BELLOW:default_msg_key = "__BELLOW";break;case S_SCREECH:default_msg_key = "__SCREECH";break;case S_BUZZ:default_msg_key = "__BUZZ";break;case S_MOAN:default_msg_key = "__MOAN";break;case S_WHINE:default_msg_key = "__WHINE";break;case S_CROAK:default_msg_key = "__CROAK";break;case S_GROWL:default_msg_key = "__GROWL";break;case S_HISS:default_msg_key = "__HISS";noise_level = 4; // not very loud -- bwrbreak;// Loudness setting for shouts that are only defined in dat/shout.txtcase S_VERY_SOFT:default_msg_key = "";noise_level = 4;break;case S_SOFT:default_msg_key = "";noise_level = 6;break;case S_NORMAL:default_msg_key = "";noise_level = 8;break;case S_LOUD:default_msg_key = "";noise_level = 10;break;case S_VERY_LOUD:default_msg_key = "";noise_level = 12;break;}// Use get_monster_data(monster->type) to bypass mon_shouts()// replacing S_RANDOM with a random value.if (mons_is_demon( monster->type ) && coinflip()&& (type != S_SILENT ||get_monster_data(monster->type)->shouts == S_RANDOM)){noise_level = 8;default_msg_key = "__DEMON_TAUNT";}std::string msg, suffix;std::string key = mons_type_name(monster->type, DESC_PLAIN);// Pandemonium demons have random names, so use "pandemonium lord"if (monster->type == MONS_PANDEMONIUM_DEMON)key = "pandemonium lord";// Search for player ghost shout by the ghost's class.else if (monster->type == MONS_PLAYER_GHOST){const ghost_demon &ghost = *(monster->ghost);std::string ghost_class = get_class_name(ghost.values[GVAL_CLASS]);key = ghost_class + " player ghost";default_msg_key = "player ghost";}// Tries to find an entry for "name seen" or "name unseen",// and if no such entry exists then looks simply for "name".if (player_monster_visible(monster))suffix = " seen";elsesuffix = " unseen";msg = getShoutString(key, suffix);if (msg == "__DEFAULT" || msg == "__NEXT")msg = getShoutString(default_msg_key, suffix);else if (msg == "")
if (!mons_friendly(monster)&& (!silenced(you.x_pos, you.y_pos)&& !silenced(monster->x, monster->y))){if (mons_is_demon( monster->type ) && coinflip()){if (monster->type == MONS_IMP|| monster->type == MONS_WHITE_IMP|| monster->type == MONS_SHADOW_IMP){imp_taunt( monster );}else{demon_taunt( monster );}}else{std::string msg = "You hear ";switch (mons_shouts(monster->type)){case S_SILENT:case NUM_SHOUTS:case S_RANDOM:msg += "buggy behaviour!";break;case S_SHOUT:msg += "a shout!";break;case S_BARK:msg += "a bark!";break;case S_SHOUT2:msg += "two shouts!";noise_level = 12;break;case S_ROAR:msg += "a roar!";noise_level = 12;break;case S_SCREAM:msg += "a hideous shriek!";break;case S_BELLOW:msg += "a bellow!";break;case S_SCREECH:msg += "a screech!";break;case S_BUZZ:msg += "an angry buzzing noise.";break;case S_MOAN:msg += "a chilling moan.";break;case S_WHINE:msg += "an irritating high-pitched whine.";break;case S_CROAK:if (coinflip())msg += "a loud, deep croak!";elsemsg += "a croak.";break;case S_GROWL:msg += "an angry growl!";break;case S_HISS:msg += "an angry hiss!";noise_level = 4; // not very loud -- bwrbreak;}msg::streams(MSGCH_SOUND) << msg << std::endl;}}
// Database keys are case-insensitve.if (isupper(mons_char(monster->type)))glyph_key += "cap-";
noisy( noise_level, monster->x, monster->y );
glyph_key += mons_char(monster->type);glyph_key += "'";msg = getShoutString(glyph_key, suffix);if (msg == "" || msg == "__DEFAULT")msg = getShoutString(default_msg_key, suffix);}if (default_msg_key == "__BUGGY")msg::streams(MSGCH_SOUND) << "You hear something buggy!"<< std::endl;else if ((msg == "" || msg == "__NONE")&& mons_shouts(monster->type) == S_SILENT); // No "visual shout" defined for silent monster, do nothingelse if (msg == ""){msg::streams(MSGCH_DIAGNOSTICS)<< "No shout entry for default shout type '"<< default_msg_key << "'" << std::endl;msg::streams(MSGCH_SOUND) << "You hear something buggy!"<< std::endl;}else if (msg == "__NONE"){msg::streams(MSGCH_DIAGNOSTICS)<< "__NONE returned as shout for non-silent monster '"<< default_msg_key << "'" << std::endl;msg::streams(MSGCH_SOUND) << "You hear something buggy!"<< std::endl;}else{msg = do_mon_str_replacements(msg, monster);if (mons_shouts(monster->type) == S_SILENT)msg::streams(MSGCH_TALK) << msg << std::endl;elsemsg::streams(MSGCH_SOUND) << msg << std::endl;
// Band members are a lot less likely to speak, since there's// a lot of them.if (testbits(monster->flags, MF_BAND_MEMBER))chance *= 10;// However, confused and fleeing monsters are more interesting.if (monster->behaviour == BEH_FLEE)chance /= 2;if (monster->has_ench(ENCH_CONFUSION))chance /= 2;if (one_chance_in(chance))mons_speaks(monster);}
monster_type speaker;const char **silenced;const char **confused;const char **confused_friend;const char **fleeing;const char **fleeing_friend;const char **friendly;const char **hostile; // Most common.};
std::string prefix = "";const int size = prefixes.size();for (int i = 0; i < size; i++){prefix += prefixes[i];prefix += " ";}
static const char *murray_silenced[] ={"%s rolls in a circle.","%s rolls around.","%s spins like a top.","%s grins evilly.","%s seems to say something.","%s says something you can't hear. It was probably not a compliment.",NULL};
std::string msg = "";msg = getSpeakString(prefix + key);if (msg != "")return msg;
static const char *murray_hostile[] ={"%s rolls in a circle.","%s rolls around.","%s spins like a top.","%s grins evilly.","%s laughs evilly.","%s cackles, \"I will rule the world!\"","%s shouts, \"Give me your head, so I can impale it on a pike!\"","%s's teeth chatter loudly.","%s yells, \"I'm a mighty demonic power!\"","%s asks, \"How could you choose the Orb over me, your best friend?\"","%s shouts, \"Let the forces of evil and voodoo overcome you!\"","%s screams, \"If I had legs, you would be dead twenty times over!\"","%s yells, \"My visage is famous all over the dungeon!\"","%s says, \"You're the second biggest fool I've ever met!\"",NULL};
// Combinations of prefixes by threesif (size >= 3){for (int i = 0; i < (size - 2); i++)for (int j = i + 1; j < (size - 1); j++)for (int k = j + 1; k < size; k++){prefix = prefixes[i] + " ";prefix += prefixes[j] + " ";prefix += prefixes[k] + " ";
static mon_dialogue vox_populi[] ={{ MONS_MURRAY, murray_silenced, NULL, NULL, NULL, NULL, NULL,murray_hostile },};static const mon_dialogue *find_dialogue(const monsters *monster){for (unsigned i = 0; i < sizeof(vox_populi) / sizeof(*vox_populi); ++i)if (vox_populi[i].speaker == monster->type)return (&vox_populi[i]);return (NULL);}static bool say_dialogue(const monsters *monster,const char **dialogue){if (!dialogue)return (false);
msg = getSpeakString("default " + prefix + key);if (msg != "")return msg;}}
int nitems = 0;for (const char **run = dialogue; *run; ++run, ++nitems);
// Combinations of prefixes by twosif (size >= 2){for (int i = 0; i < (size - 1); i++)for (int j = i + 1; j < size; j++){prefix = prefixes[i] + " ";prefix += prefixes[j] + " ";
static bool say_specific_dialogue(const monsters *monster,const mon_dialogue *dialogue)
// Player ghosts with different classes can potentially speak different// things.static std::string player_ghost_speak_str(const monsters *monster,const std::vector<std::string> prefixes)
int temp_rand; // probability determination// This function is a little bit of a problem for the message channels// since some of the messages it generates are "fake" warning to// scare the player. In order to accomidate this intent, we're// falsely categorizing various things in the function as spells and// danger warning... everything else just goes into the talk channel -- bwrmsg_channel_type msg_type = MSGCH_TALK;const std::string m_name = monster->name(DESC_CAP_THE);strcpy(info, m_name.c_str());
// Invisible monster tries to remain unnoticed. Unless they're// confused, since then they're too confused to realize they// should stay silent, but only if the player can see them, so as// to not have to deal with cases of speaking monsters which the// player can't see.if (monster->invisible() && !(player_monster_visible(monster)&& monster->has_ench(ENCH_CONFUSION)))return false;
if (monster->invisible())
// Dealing with the monster not being silenced while the player// *is* silenced, and is hence able to see the monsters' gestures// and such but not hear any sounds it makes, would be a big// headache to deal with, so skip it.if (!silenced(monster->x, monster->y)&& silenced(you.x_pos, you.y_pos))
const mon_dialogue *dialogue = find_dialogue(monster);if (dialogue)return (say_specific_dialogue(monster, dialogue));//mv: if it's also invisible, program never gets hereif (silenced(monster->x, monster->y)){
// Silenced monsters only "speak" 1/3 as often as non-silenced,// unless they're normally silent (S_SILENT). Use// get_monster_data(monster->type) to bypass mon_shouts()// replacing S_RANDOM with a random value.if (silenced(monster->x, monster->y)&& get_monster_data(monster->type)->shouts != S_SILENT)
if (monster->has_ench(ENCH_CONFUSION)){temp_rand = random2(10);strcat(info, (temp_rand < 4) ? " gestures wildly." :(temp_rand == 4) ? " looks confused." :(temp_rand == 5) ? " grins evilly." :(temp_rand == 6) ? " smiles happily." :(temp_rand == 7) ? " cries.": " says something but you don't hear anything.");}else if (monster->behaviour == BEH_FLEE){temp_rand = random2(10);strcat(info,(temp_rand < 3) ? " glances furtively about." :(temp_rand == 3) ? " opens its mouth, as if shouting." :(temp_rand == 4) ? " looks around." :(temp_rand == 5) ? " appears indecisive." :(temp_rand == 6) ? " ponders the situation.": " seems to say something.");}// disregard charmed critters.. they're not too expressiveelse if (monster->attitude == ATT_FRIENDLY){temp_rand = random2(10);strcat(info, (temp_rand < 3) ? " gives you a thumbs up." :(temp_rand == 3) ? " looks at you." :(temp_rand == 4) ? " waves at you." :(temp_rand == 5) ? " smiles happily.":(temp_rand == 6) ? " winks at you.": " says something you can't hear.");}else{temp_rand = random2(10);strcat(info, (temp_rand < 3) ? " gestures." :(temp_rand == 3) ? " gestures obscenely." :(temp_rand == 4) ? " grins." :(temp_rand == 5) ? " looks angry." :(temp_rand == 6) ? " seems to be listening.": " says something but you don't hear anything.");} //end switch silenced monster's behaviourmpr(info, MSGCH_TALK);return true;} // end silenced monster
prefixes.push_back("confused");std::string msg;// __NONE means to be silent, and __NEXT means to try the next,// less exact method of describing the monster to find a speech// string.// First, try its exact nameif (monster->type == MONS_PLAYER_GHOST)// Player ghosts are treated differently.msg = player_ghost_speak_str(monster, prefixes);else if (monster->type == MONS_PANDEMONIUM_DEMON)// Pandemonium demons have randomly generated names,// so use "pandemonium lord" instead.msg = get_speak_string(prefixes, "pandemonium lord", monster);elsemsg = get_speak_string(prefixes, monster->name(DESC_PLAIN), monster);if (msg == "__NONE")return false;// Now that we're not dealing with a specific monster name, include// whether or not it can move in the prefixif (mons_is_stationary(monster))prefixes.insert(prefixes.begin(), "stationary");// Names for the monster, its species and its genus all failed,// so try the monster's glyph/symbol.if (msg == "" || msg == "__NEXT")
if (mons_friendly(monster)){switch (random2(18)) // speaks for friendly confused monsters{case 0:strcat(info, " prays for help.");break;case 1:strcat(info, " screams, \"Help!\"");break;case 2:strcat(info, " shouts, \"I'm losing control!\"");break;case 3:strcat(info, " shouts, \"What's happening?\"");break;case 4:case 5:strcat(info, " gestures wildly.");break;case 6:strcat(info, " cries.");break;case 7:strcat(info, " shouts, \"Yeah!\"");break;case 8:strcat(info, " sings.");break;case 9:strcat(info, " laughs crazily.");break;case 10:strcat(info, " ponders the situation.");break;case 11:strcat(info, " grins madly.");break;case 12:strcat(info, " looks very confused.");break;case 13:strcat(info, " mumbles something.");break;case 14:strcat(info, " giggles crazily.");break;case 15:strcat(info, " screams, \"");strcat(info, you.your_name);strcat(info, "! Help!\"");break;case 16:strcat(info, " screams, \"");strcat(info, you.your_name);strcat(info, "! What's going on?\"");break;case 17:strcat(info, " says, \"");strcat(info, you.your_name);strcat(info, ", I'm a little confused.\"");break;}}else{switch (random2(23)) // speaks for unfriendly confused monsters{case 0:strcat(info, " yells, \"Get them off me!\"");break;case 1:strcat(info, " screams, \"I will kill you anyway!\"");break;case 2:strcat(info, " shouts, \"What's happening?\"");break;case 3:case 4:case 5:strcat(info, " gestures wildly.");break;case 6:strcat(info, " cries.");break;case 7:strcat(info, " shouts, \"NO!\"");break;case 8:strcat(info, " shouts, \"YES!\"");break;case 9:strcat(info, " laughs crazily.");break;case 10:strcat(info, " ponders the situation.");break;case 11:strcat(info, " grins madly.");break;case 12:strcat(info, " looks very confused.");break;case 13:strcat(info, " mumbles something.");break;case 14:strcat(info, " says, \"I'm a little confused.\"");break;case 15:strcat(info, " asks, \"Where am I?\"");break;case 16:strcat(info, " shakes.");break;case 17:strcat(info, " asks, \"Who are you?\"");break;case 18:strcat(info, " asks, \"What the hell are we doing here? Mmm, I see...\"");break;case 19:strcat(info, " cries, \"My head! MY HEAD!!!\"");break;case 20:strcat(info, " says, \"Why is everything spinning?\"");break;case 21:strcat(info, " screams, \"NO! I can't bear that much noise!\"");break;case 22:strcat(info, " is trying to cover his eyes.");break;}}
// Database keys are case-insensitve.if (isupper(mons_char(monster->type)))key += "cap-";
else if (monster->has_ench(ENCH_HELD))
if (msg == "__NONE")return false;// Monster symbol didn't work, try monster shape. Since we're// dealing with just the monster shape, change the prefix to// include info on if the monster's intelligence is at odds with// its shape.mon_body_shape shape = get_mon_shape(monster);mon_intel_type intel = mons_intel(monster->type);if (shape >= MON_SHAPE_HUMANOID && shape <= MON_SHAPE_NAGA&& intel < I_NORMAL)prefixes.insert(prefixes.begin(), "stupid");else if (shape >= MON_SHAPE_QUADRUPED && shape <= MON_SHAPE_FISH)
switch(random2(8)){case 0:strcat(info, " says, \"Help me, ");strcat(info, you.your_name);strcat(info, ", please!\"");break;case 1:strcat(info, " cries, \"MUMMY!\"");break;case 2:strcat(info, " shouts, \"");strcat(info, you.your_name);strcat(info, "! Can't you see I need your help?\"");break;case 3:strcat(info, " shouts, \"I could do with a little help here, you know.\"");break;case 4:strcat(info, " mumbles something.");break;case 5:strcat(info, " says, \"Umm, ");strcat(info, you.your_name);strcat(info, "? Help?\"");break;case 6:strcat(info, " cries.");break;case 7:strcat(info, " cries, \"Why me?");break;}
if (intel > I_INSECT)prefixes.insert(prefixes.begin(), "smart");else if (intel < I_INSECT)prefixes.insert(prefixes.begin(), "stupid");
switch(random2(12)){case 0:strcat(info, " screams, \"HEY! This isn't fair!\"");break;case 1:strcat(info, " screams, \"Help! Get me out of here!\"");break;case 2:strcat(info, " begs, \"Could you help me? I swear I won't hurt you.\"");break;case 3:strcat(info, " yells, \"LEMME GO!\"");break;case 4:strcat(info, " cries, \"Please! I'll never do it again!\"");break;case 5:strcat(info, " mutters, \"Just what did I do to deserve this?\"");break;case 6:strcat(info, " asks, \"Hey, want to switch places?\"");break;case 7:strcat(info, " cries, \"I hate you!\"");break;case 8:strcat(info, " snarls, \"This is all your fault!\"");break;case 9:strcat(info, " says, \"I meant to do this, just so you know.\"");break;case 10:strcat(info, " shouts, \"This is all a huge misunderstanding!");break;case 11:strcat(info, " cries, \"Why me?\"");break;}
if (intel > I_ANIMAL)prefixes.insert(prefixes.begin(), "smart");else if (intel < I_ANIMAL)prefixes.insert(prefixes.begin(), "stupid");
if (mons_holiness( monster ) == MH_DEMONIC&& monster->type != MONS_IMP){return (false);}if (mons_friendly(monster)){switch (random2(11)){case 0:snprintf( info, INFO_SIZE, "%s %s, \"WAIT FOR ME!\"",m_name.c_str(), coinflip() ? "shouts" : "yells");strcat(info, you.your_name);strcat(info, ", could you help me?\"");break;case 1:strcat(info, " screams, \"Help!\"");break;case 2:strcat(info, " shouts, \"Cover me!\"");break;case 3:strcat(info, " screams, \"");strcat(info, you.your_name);strcat(info, "! Help me!\"");break;case 4:case 5:case 6:strcat(info, " tries to hide somewhere.");break;case 7:strcat(info, " prays for help.");break;case 8:strcat(info, " looks at you beseechingly.");break;case 9:strcat(info, " shouts, \"Protect me!\"");break;case 10:strcat(info, " cries, \"Don't forget your friends!\"");break;}}else{switch (random2(20)) // speaks for unfriendly fleeing monsters{case 0:snprintf( info, INFO_SIZE, "%s %s, \"Help!\"", m_name.c_str(),coinflip()? "yells" : "wails");break;case 1:snprintf( info, INFO_SIZE, "%s %s, \"Help!\"", m_name.c_str(),coinflip() ? "cries" : "screams"); break;case 2:snprintf( info, INFO_SIZE, "%s %s, \"Why can't we all just get along?\"",m_name.c_str(), coinflip() ? "begs" : "pleads");break;case 3:snprintf( info, INFO_SIZE, "%s %s trips in trying to escape.", m_name.c_str(),coinflip() ? "nearly" : "almost");break;case 4:snprintf( info, INFO_SIZE, "%s %s, \"Of all the rotten luck!\"", m_name.c_str(),coinflip() ? "mutters" : "mumbles");break;case 5:snprintf( info, INFO_SIZE, "%s %s, \"Oh dear! Oh dear!\"", m_name.c_str(),coinflip() ? "moans" : "wails");case 6:snprintf( info, INFO_SIZE, "%s %s, \"Damn and blast!\"", m_name.c_str(),coinflip() ? "mutters" : "mumbles");break;case 7:strcat(info, " prays for help.");break;case 8:strcat(info, " shouts, \"No! I'll never do that again!\"");break;case 9:snprintf( info, INFO_SIZE, "%s %s", m_name.c_str(),coinflip() ? "begs for mercy." : "cries, \"Mercy!\"");break;case 10:snprintf( info, INFO_SIZE, "%s %s, \"%s!\"", m_name.c_str(),coinflip() ? "blubbers" : "cries",coinflip() ? "Mommeee" : "Daddeee");break;case 11:snprintf( info, INFO_SIZE, "%s %s, \"Please don't kill me!\"", m_name.c_str(),coinflip() ? "begs" : "pleads");break;case 12:snprintf( info, INFO_SIZE, "%s %s, \"Please don't hurt me!\"", m_name.c_str(),coinflip() ? "begs" : "pleads");break;case 13:snprintf( info, INFO_SIZE, "%s %s, \"Please, I have a lot of children...\"",m_name.c_str(), coinflip() ? "begs" : "pleads");break;case 14:strcat(info, " tries to recover lost courage.");break;case 15:case 16:case 17:strcat(info, " gives up.");break;case 19:snprintf( info, INFO_SIZE, "%s looks really %s.",m_name.c_str(),coinflip() ? "scared stiff" : "rattled");break;}}
if (intel > I_INSECT)prefixes.insert(prefixes.begin(), "smart");else if (intel < I_INSECT)prefixes.insert(prefixes.begin(), "stupid");
else if (mons_friendly(monster))
else if (shape >= MON_SHAPE_PLANT && shape <= MON_SHAPE_BLOB&& intel > I_PLANT)prefixes.insert(prefixes.begin(), "smart");if (msg == "" || msg == "__NEXT")msg = get_speak_string(prefixes, get_mon_shape_str(shape), monster);if (msg == "__NONE")return false;// If we failed to get a message with a winged or tailed humanoid,// or a naga or centaur, try moving closer to plain humanoidif ((msg == "" || msg == "__NEXT") && shape > MON_SHAPE_HUMANOID&& shape <= MON_SHAPE_NAGA)
if (mons_holiness( monster ) == MH_DEMONIC&& monster->type != MONS_IMP)
// If a humanoid monster has both wings and a tail, try// removing one and then the other to see if we get any// results.if (shape == MON_SHAPE_HUMANOID_WINGED_TAILED)
// friendly imps are too common so they speak very very rarelyif (monster->type == MONS_IMP){if (!one_chance_in(10))return (false);switch (random2(12))
// Only be silent if both tailed and winged return __NONEif (msg == "" || msg == "__NONE" || msg == "__NEXT")
case 0:strcat(info, " says, \"Just tell me who NOT to kill.\"");break;case 1:strcat(info, " says, \"OK Boss!\"");break;case 2:strcat(info, " grins impishly at you.");break;case 3:strcat(info, " picks up some beetles from the floor ""and offers them to you.");break;case 4:strcat(info, " blows smoke rings.");break;case 5:strcat(info, " shouts, \"Over here! I found it!\"");break;case 6:strcat(info, " says, \"The Orb is all yours.\"");break;case 7:strcat(info, " says, \"Isn't this more fun with friends?\"");break;case 8:strcat(info, " says, \"Uh-oh! Wait. OK.\"");break;case 9:strcat(info, " shouts, \"Stay back! It could be a trick.\"");break;case 10:strcat(info, " says, \"You're so much nicer than ""my last boss.\"");break;case 11:strcat(info, " jumps up and down with excitement.\"");break;}}else{switch (random2(18)){case 0:strcat(info, " yells, \"Run! I'll cover you!\"");break;case 1:strcat(info, " shouts, \"Die, monster!\"");break;case 2:strcat(info, " says, \"It's nice to have friends.\"");break;
shape = MON_SHAPE_HUMANOID_WINGED;std::string msg2;msg2 = get_speak_string(prefixes,get_mon_shape_str(shape),monster);if (msg == "__NONE" && msg2 == "__NONE")return false;
case 3:strcat(info, " looks at you.");break;case 4:strcat(info, " smiles at you.");break;case 5:strcat(info, " says, \"");strcat(info, you.your_name);strcat(info, ", you are my only friend.\"");break;case 6:strcat(info, " says, \"");strcat(info, you.your_name);strcat(info, ", I like you.\"");break;
if (msg2 == "__NONE")msg2 = "";
case 7:strcat(info, " waves at you.");break;case 8:strcat(info, " says, \"Be careful!\"");break;case 9:strcat(info, " says, \"Don't worry. I'm here with you.\"");break;case 10:strcat(info, " smiles happily.");break;case 11:strcat(info, " shouts, \"No mercy! Kill them all!");break;case 12:strcat(info, " winks at you.");break;case 13:strcat(info, " says, \"Me and you. It sounds cool.\"");break;case 14:strcat(info, " says, \"I'll never leave you.\"");break;case 15:strcat(info, " says, \"I would die for you.\"");break;case 16:strcat(info, " shouts, \"Beware of monsters!\"");break;case 17:strcat(info, " looks friendly.");break;
msg = msg2;
switch (monster->type){case MONS_TERENCE: // fighter who likes to killswitch (random2(15)){case 0:strcat(info, " screams, \"I'm going to kill you! \"");break;case 1:strcat(info, " shouts, \"Now you die.\"");break;case 2:strcat(info, " says, \"Rest in peace.\"");break;case 3:snprintf( info, INFO_SIZE, "%s shouts, \"%s!!!\"",m_name.c_str(), coinflip() ? "ATTACK" : "DIE");break;case 4:strcat(info, " says, \"How do you enjoy it?\"");break;case 5:strcat(info, " shouts, \"Get ready for death!\"");break;case 6:strcat(info, " says, \"You are history.\"");break;case 7:strcat(info, " says, \"Do you want it fast or slow?.\"");break;case 8:strcat(info, " says, \"Did you write a testament? You should...\"");break;case 9:strcat(info, " says, \"Time to say good-bye...\"");break;case 10:snprintf( info, INFO_SIZE, "%s says, \"Don't try to defend, it's %s.\"",m_name.c_str(), coinflip() ? "pointless" : "senseless");break;case 11:strcat(info, " bares his teeth.");break;case 12:snprintf( info, INFO_SIZE, "%s says, \"I'll show you few %s.\"",m_name.c_str(), coinflip() ? "tricks" : "ploys.");break;case 13:strcat(info, " screams, \"I want your blood.\"");break;case 14:strcat(info, " looks scornfully at you.");break;}break; // end Terence
msg::streams(MSGCH_DIAGNOSTICS)<< "__NEXT used by shape-based speech string for monster '"<< monster->name(DESC_PLAIN) << "'" << std::endl;return false;}
case MONS_EDMUND: // mercenaries guarding dungeoncase MONS_LOUISE:case MONS_FRANCES:case MONS_DUANE:case MONS_FREDERICK:switch (random2(17)){case 0:strcat(info, " screams, \"I'm going to kill you! Now!\"");break;case 1:strcat(info," shouts, \"Return immediately or I'll kill you!\"");break;case 2:strcat(info," says, \"Now you've reached the end of your journey!\"");break;case 3:strcat(info," screams, \"One false step and I'll kill you!\"");break;case 4:strcat(info, " says, \"Drop everything you've found here and return home.\"");break;case 5:strcat(info, " shouts, \"You will never get the Orb.\"");break;case 6:strcat(info, " looks very unfriendly.");break;case 7:strcat(info, " looks very cold.");break;case 8:strcat(info, " shouts, \"It's the end of the party!\"");break;case 9:strcat(info, " says, \"Return every stolen item!\"");break;case 10:strcat(info, " says, \"No trespassing is allowed here.\"");break;case 11:strcat(info, " grins evilly.");break;case 12:strcat(info, " screams, \"You must be punished!\"");break;case 13:strcat(info, " says, \"It's nothing personal...\"");break;case 14:strcat(info, " says, \"A dead adventurer is a good adventurer.\"");break;case 15:strcat(info, " says, \"Coming here was your last mistake.\"");break;case 16:strcat(info, " shouts, \"Intruder!\"");break;}break; // end Edmund & Co
// We have a speech string, now parse and act on it.msg = do_mon_str_replacements(msg, monster);
case MONS_JOSEPH:switch (random2(16)){case 0:strcat(info, " smiles happily.");break;case 1:strcat(info, " says, \"I'm happy to see you. And I'll be happy to kill you.\"");break;case 2:strcat(info, " says, \"I've waited for this moment for such a long time.\"");break;case 3:strcat(info," says, \"It's nothing personal, but I have to kill you.\"");break;case 5:strcat(info, " says, \"You will never get the Orb, sorry.\"");break;case 9:strcat(info, " shouts, \"I love to fight! I love killing!\"");break;case 10:strcat(info," says, \"I'm here to kill trespassers. I like my job.\"");break;case 11:strcat(info, " tries to grin evilly.");break;case 12:strcat(info," says, \"You must be punished! Or... I want to punish you!\"");break;case 13:strcat(info," sighs, \"Being a guard is usually so boring...\"");break;case 14:strcat(info, " shouts, \"At last some action!\"");break;case 15:strcat(info, " shouts, \"Wow!\"");break;}break; // end Joseph
std::vector<std::string> lines = split_string("\n", msg);
case MONS_ORC_HIGH_PRIEST: // priest, servants of dark ancient godcase MONS_DEEP_ELF_HIGH_PRIEST:switch (random2(12)){case 0:case 1:strcat(info, " prays.");msg_type = MSGCH_MONSTER_SPELL;break;
for (int i = 0, size = lines.size(); i < size; i++){std::string line = lines[i];
case 2:strcat(info, " mumbles some strange prayers.");msg_type = MSGCH_MONSTER_SPELL;break;
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;}
case 3:strcat(info," shouts, \"You are a heretic and must be destroyed.\"");break;case 4:strcat(info, " says, \"All sinners must die.\"");break;
// This function is a little bit of a problem for the message// channels since some of the messages it generates are "fake"// warning to scare the player. In order to accomidate this// intent, we're falsely categorizing various things in the// function as spells and danger warning... everything else// just goes into the talk channel -- bwrmsg_channel_type msg_type = MSGCH_TALK;
case 5:strcat(info, " looks excited.");break;case 6:strcat(info, " says, \"You will make a fine sacrifice.\"");break;case 7:strcat(info, " starts to sing a prayer.");break;case 8:strcat(info, " shouts, \"You must be punished.\"");break;case 9:strcat(info, " intones a terrible prayer.");msg_type = MSGCH_MONSTER_SPELL;break;case 10:strcat(info, " says, \" Right in the middle of my ""sermon, too.\"");break;case 11:strcat(info, " says, \"The wages of sin are death, ""you know.\"");break;}break; // end priestscase MONS_ORC_SORCERER: // hateful wizards, using strange powerscase MONS_DEEP_ELF_SORCERER:case MONS_WIZARD:switch (random2(19)){case 0:case 1:case 2:strcat(info, " wildly gestures.");mpr( info, MSGCH_MONSTER_SPELL );if (coinflip())canned_msg( MSG_NOTHING_HAPPENS );elsecanned_msg( MSG_YOU_RESIST );return (true);
std::string::size_type pos = line.find(":");
case 3:case 4:case 5:strcat(info, " mumbles some strange words.");mpr( info, MSGCH_MONSTER_SPELL );if (coinflip())canned_msg( MSG_NOTHING_HAPPENS );elsecanned_msg( MSG_YOU_RESIST );return (true);case 6:strcat(info, " shouts, \"You can't withstand my power!\"");break;case 7:strcat(info, " shouts, \"You are history.\"");break;case 8:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, " becomes transparent for a moment.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 9:strcat(info, " throws some strange powder towards you.");msg_type = MSGCH_MONSTER_SPELL;break;case 10:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, " glows brightly for a moment.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 11:strcat(info, " says, \"argatax netranoch dertex\"");msg_type = MSGCH_MONSTER_SPELL;break;case 12:strcat(info, " says, \"dogrw nutew berg\"");msg_type = MSGCH_MONSTER_SPELL;break;
if (pos != std::string::npos){std::string param = line.substr(0, pos);bool match = true;
break;case 14:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);strcpy(info, m_name.c_str());strcat(info, " becomes larger for a moment.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 15:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);strcpy(info, m_name.c_str());strcat(info, "'s fingertips start to glow.");
else if (param == "ENCHANT")
break;case 16:strcat(info, "'s eyes start to glow.");msg_type = MSGCH_MONSTER_SPELL;break;case 17:strcat(info, " tries to paralyze you with his gaze.");msg_type = MSGCH_MONSTER_SPELL;break;case 18:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);canned_msg( MSG_YOU_RESIST );return (true);}break; // end wizardscase MONS_JESSICA: // sorceress disturbed by playerswitch (random2(10)){case 0:strcat(info, " grins evilly.");break;case 1:strcat(info, " says, \"I'm really upset.\"");break;case 2:strcat(info, " shouts, \"I don't like beings like you.\"");break;case 3:strcat(info," shouts, \"Stop bothering me, or I'll kill you!\"");break;case 4:strcat(info, " very coldly says, \"I hate your company.\"");break;case 5:strcat(info, " mumbles something strange.");msg_type = MSGCH_MONSTER_SPELL;break;case 6:strcat(info, " looks very angry.");break;case 7:strcat(info," shouts, \"You're disturbing me. I'll have to kill you.\"");break;case 8:strcat(info, " screams, \"You are a ghastly nuisance!\"");break;case 9:strcat(info, " gestures wildly.");msg_type = MSGCH_MONSTER_SPELL;break;}break; // end Jessicacase MONS_SIGMUND: // mad old wizardswitch (random2(19)){case 0:case 1:case 2:strcat(info, " laughs crazily.");break;case 3:strcat(info, " says, \"Don't worry, I'll kill you fast.\"");break;case 4:strcat(info, " grinds his teeth.");break;case 5:strcat(info, " asks, \"Do you like me?\"");break;case 6:strcat(info, " screams, \"Die, monster!\"");break;case 7:strcat(info, " says, \"You will soon forget everything.\"");break;case 8:strcat(info, " screams, \"You will never... NEVER!\"");break;case 9:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, "'s eyes start to glow with a red light. ");msg_type = MSGCH_MONSTER_ENCHANT;break;case 10:strcat(info, " says, \"Look into my eyes.\"");break;case 11:strcat(info, " says, \"I'm your fate.\"");break;case 12:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, " is suddenly surrounded by pale blue light.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 13:strcat(info, " tries to bite you.");break;case 14:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, " is suddenly surrounded by pale green light.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 15:strcat(info, " screams, \"I am the angel of Death!\"");break;case 16:strcat(info, " screams, \"Only death can liberate you!\"");break;case 17:strcat(info, " whispers, \"You'll know eternity soon...\"");break;case 18:strcat(info, " screams, \"Don't try to resist!\"");break;}break; // end Sigmundcase MONS_IMP: // small demoncase MONS_WHITE_IMP:case MONS_SHADOW_IMP:if (one_chance_in(3)){imp_taunt( monster );return (true);}
else if (param == "PLAIN")msg_type = MSGCH_PLAIN;
{switch (random2(11)){case 0:strcat(info, " laughs crazily.");break;case 1:strcat(info, " grins evilly.");break;case 2:strcat(info, " breathes smoke at you.");break;case 3:strcat(info, " lashes his tail.");break;case 4:strcat(info, " grinds his teeth.");break;case 5:strcat(info, " sputters.");break;case 6:strcat(info, " breathes steam at you.");break;case 7:strcat(info, " spits at you.");break;case 8:strcat(info, " disappears for a moment.");break;case 9:strcat(info, " summons a swarm of flies.");break;case 10:strcat(info, " picks up a beetle and eats it.");break;}}break; // end imp
match = false;
case MONS_TORMENTOR: // cruel devilif (one_chance_in(10)){demon_taunt( monster );return (true);}else{switch (random2(18)){case 0:strcat(info, " laughs crazily.");break;case 1:strcat(info, " grins evilly.");break;case 2:strcat(info, " says, \"I am all your nightmares come true.\"");break;case 3:strcat(info, " says, \"I will show you what pain is.\"");break;case 4:strcat(info, " shouts, \"I'll tear you apart.\"");break;case 5:strcat(info," says, \"You will wish to die when I get to you.\"");break;case 6:strcat(info, " says, \"I will drown you in your own blood.\"");break;case 7:strcat(info," screams, \"You will die horribly!\"");break;case 8:strcat(info, " says, \"I will eat your liver.\"");break;case 9:strcat(info, " grins madly.");break;case 10:strcat(info, " shouts, \"Prepare for my thousand needles of pain!\"");break;case 11:strcat(info," says, \"I know a thousand and one ways to kill you.\"");break;case 12:strcat(info," says, \"I'll show you my torture chamber!\"");break;case 13:case 14:strcat(info," says, \"I'll crush your bones, one by one.\"");break;case 15:strcat(info, " says, \"I know your fate. It's pain.\"");break;case 16:strcat(info, " says, \"Get ready! Throes await you.\"");break;case 17:strcat(info, " grins malevolently.");break;}}break; // end tormentorcase MONS_PANDEMONIUM_DEMON: // named demonscase MONS_GERYON:case MONS_ASMODEUS:case MONS_DISPATER:case MONS_ANTAEUS:case MONS_ERESHKIGAL:case MONS_MNOLEG:case MONS_LOM_LOBON:case MONS_CEREBOV:case MONS_GLOORX_VLOQ:demon_taunt( monster );return (true);case MONS_PLAYER_GHOST: // ghost of unsuccesful playerswitch (random2(29)){case 0:strcat(info, " laughs crazily.");break;case 1:strcat(info, " grins evilly.");break;case 2:strcat(info, " shouts, \"You will never get the ORB!\"");break;case 3: // mv: ghosts are usually wailing, aren't ?strcat(info, " says, \"I have seen your future. ""And it's all used up.\"");break;case 4:strcat(info, " makes a sound of rattling chains.");break;case 5:strcat(info, " says, \"They lied to you. ""The Dungeon just goes down and down forever.\"");break;case 6:strcat(info, " says, \"Do you think the gods ""will protect you?\"");break;case 7:strcat(info, " says, \"I was like you once.\"");break;case 8:strcat(info, " says, \"Very impressive. But it won't help. ""Nothing will.\"");break;case 9:strcat(info, " whispers, \"They're coming for you...\"");break;case 10:strcat(info, " says, \"What have you got ""that I didn't have?\"");break;case 11:strcat(info, " wails.");break;case 12:strcat(info, " stares at you.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel cold.", MSGCH_WARN);return (true);case 13:strcat(info, " screams, \"You will join me soon!\"");break;case 14:strcat(info, " wails, \"To die, to sleep, no more.\"");break; //Hamletcase 15:strcat(info," screams, \"You must not succeed where I failed.\"");break;case 16:strcat(info," screams, \"I'll kill anyone who wants the ORB.\"");break;case 17:strcat(info, " whispers, \"Meet emptiness of death!\"");break;case 18:strcat(info, " whispers, \"Death is liberation.\"");break;case 19:strcat(info," whispers, \"Everlasting silence awaits you.\"");break;case 20:strcat(info," screams, \"Don't try to defend. You have no chance!\"");break;case 21:strcat(info," whispers, \"Death doesn't hurt. What you feel is life.\"");break;case 22:strcat(info, " whispers, \"The ORB doesn't exist.\"");break;case 23:strcat(info, " wails, \"Death is your only future.\"");break;case 24:strcat(info, " says, \"The more you struggle now, ""the more you'll suffer later.\"");break;case 25:strcat(info, " whispers, \"Trust me. Just give in.\"");break;case 26:strcat(info, " says very slowly, \"There's no hope.\"");break;case 27:strcat(info, " lets out a mournful wail.");break;case 28:strcat(info, " keens inconsolably.");break;}break; // end players ghostcase MONS_PSYCHE: // insane girlswitch (random2(20)){case 0:strcat(info, " smiles happily.");break;case 1:strcat(info, " giggles crazily.");break;case 2:strcat(info, " cries.");break;case 3:strcat(info, " stares at you for a moment.");break;case 4:strcat(info, " sings.");break;case 5:strcat(info," says, \"Please, could you die a little faster?\"");break;case 6:strcat(info," says, \"I'm a bad girl. But I can't do anything about it.\"");break;case 7:strcat(info," screams, \"YOU ARE VIOLATING AREA SECURITY!\"");break;case 8:strcat(info, " cries, \"I hate blood and violence.\"");break;case 9:strcat(info," screams, \"Peace! Flowers! Freedom! Dead adventurers!\"");break;case 10:strcat(info," says, \"I'm so lonely. Only corpses are my friends.\"");break;case 11:strcat(info, " cries, \"You've killed my pet.\"");break;case 12:strcat(info," cries, \"You want to steal my orb collection?!\"");break;case 13:strcat(info, " sings a strange song.");break;case 14:strcat(info, " bursts into tears.");break;case 15:strcat(info, " sucks her thumb.");break;case 16:strcat(info," whispers, \"Hold me, thrill me, kiss me, kill me.\"");break; //(c) U2 ?case 17:strcat(info, " says, \"I'll kill you and take you home.\"");break;case 18:strcat(info," shouts, \"Well, maybe I'm nutty, but who cares?\"");break;case 19:strcat(info," shouts, \"I hope that you are sorry for that.\"");break;}break; // end Psychecase MONS_DONALD: // adventurers hating competitioncase MONS_WAYNE:switch (random2(11)){case 0:strcat(info, " screams, \"Return home!\"");break;case 1:strcat(info, " screams, \"The Orb is mine!\"");break;case 2:strcat(info, " screams, \"Give me all your treasure!\"");break;case 3:strcat(info, " screams, \"You will never get the Orb!\"");break;case 4:strcat(info, " screams, \"I was here first!\"");break;case 5:strcat(info, " frowns.");break;case 6:strcat(info, " looks very upset.");break;case 7:strcat(info, " screams, \"Get away or die!\"");break;case 8:strcat(info, " screams, \"Die!\"");break;case 9:strcat(info, " screams, \"First you have to pass me!\"");break;case 10:strcat(info, " screams, \"I hate you!\"");break;}break; // end Donaldcase MONS_MICHAEL: // spellcaster who wanted to be aloneswitch (random2(11)){case 0:strcat(info, " looks very angry.");break;case 1:strcat(info, " frowns.");break;case 2:strcat(info, " screams, \"I want to be alone!\"");break;case 3:strcat(info, " says, \"You are really a nuisance.\"");break;case 4:strcat(info," screams, \"I wanted to be alone. And you...\"");break;case 5:strcat(info, " screams, \"Get away! Or better yet, die!\"");break;case 6:strcat(info, " mumbles some strange words.");msg_type = MSGCH_MONSTER_SPELL;break;case 7:strcat(info, " points at you.");mpr(info, MSGCH_MONSTER_SPELL);canned_msg(MSG_YOU_RESIST);return (true);case 8:strcat(info, " shakes with wrath.");break;case 9:strcat(info, " drinks a potion.");break;case 10:strcat(info, " gestures wildly.");msg_type = MSGCH_MONSTER_SPELL;break;}break; // end Michaelcase MONS_ERICA: // wild tempered adventuressswitch (random2(12)){case 0:strcat(info, " screams, \"Die!\"");break;case 1:strcat(info, " screams, \"Do you want it fast or slow?\"");break;case 2:strcat(info, " looks angry.");break;case 3:strcat(info, " drinks a potion.");break;case 4:strcat(info, " says, \"I'm so much better than you.\"");break;case 5:strcat(info," says, \"Fast and perfect. Such is my way of killing.\"");break;case 6:strcat(info, " screams, \"Hurry! Death awaits!\"");break;case 7:strcat(info, " laughs wildly.");break;case 8:strcat(info, " screams, \"I'll never tell where it is!\"");break;case 9:strcat(info, " screams, \"You'll never get it!\"");break;case 10:strcat(info, " screams, \"Coming here was suicide!\"");break;case 11:strcat(info," says, \"I love to fight, but killing is better.\"");break;}break; // end Ericacase MONS_JOSEPHINE: // ugly old witch looking for somone to killswitch (random2(13)){case 0:case 1:case 2:strcat(info, " grins evilly.");break;case 3:case 4:strcat(info, " screams, \"I will kill you!\"");break;case 5:strcat(info, " grinds her teeth.");break;case 6:strcat(info, " grins malevolently.");break;case 7:strcat(info, " laughs insanely.");break;case 8:strcat(info, " screams, \"Die!\"");break;case 9:strcat(info," screams, \"I have something special for you!\"");break;case 10:strcat(info," screams, \"I'll use your head as decoration in my hut!\"");break;case 11:strcat(info, " says, \"I'll make a rug of your skin.\"");break;case 12:strcat(info, " says, \"How about some decapitation?\"");break;}break; // end Josephinecase MONS_HAROLD: // middle aged man, hired to kill you. He is in a hurry.switch (random2(11)){case 0:strcat(info, " looks nervous.");break;case 1:strcat(info, " screams, \"Hurry up!\"");break;case 2:strcat(info, " screams, \"Could you die faster?\"");break;case 3:strcat(info," says, \"Stand still. I'm trying to kill you.\"");break;case 4:strcat(info, " screams, \"Die!\"");break;case 5:strcat(info, " says, \"I hope you die soon!\"");break;case 6:strcat(info," says, \"Only a few hits and it's over.\".");break;case 7:strcat(info, " says, \"You know, I'm in a hurry.\"");break;case 8:strcat(info, " screams, \"I'll finish you soon!\"");break;case 9:strcat(info, " screams, \"Don't delay it.\"");break;case 11:strcat(info, " says, \"Mine is not to reason why. Mine's to do, yours to die.\"" );}break; // end Harold// skilled warrior looking for some fame. More deads = more famecase MONS_NORBERT:switch (random2(13)){case 0:strcat(info, " smiles happily.");break;case 1:strcat(info, " screams, \"Die, monster!\"");break;case 2:strcat(info, " screams, \"I'm a hero!\"");break;case 3:strcat(info, " shouts, \"YES! Another notch!\"");break;case 4:strcat(info, " says, \"A pity your head will make such an ugly trophy.\"");break;case 5:strcat(info," screams, \"Pray, because you'll die soon!\"");break;case 6:strcat(info," asks \"Did you write a will? You should.\".");break;case 7:strcat(info," says, \"I love killing ugly monsters like you.\"");break;case 8:strcat(info, " screams, \"Blood and destruction!\"");break;case 9:strcat(info, " says, \"You know, it's an honour to die by my hand.\"");break;case 10:strcat(info, " shouts, \"Your time has come!\"");break;case 11:strcat(info," says, \"I'm sorry but you don't have a chance.\"");break;case 12:strcat(info," says, \"Another dead monster... It must be my lucky day!\"");break;}break; // end Norbertcase MONS_JOZEF: // bounty hunterswitch (random2(14)){case 0:strcat(info, " looks satisfied.");break;case 1:strcat(info, " screams, \"Die!\"");break;case 2:strcat(info, " screams, \"At last I found you!\"");break;case 3:strcat(info, " shouts, \"I'll get 500 for your head!\"");break;case 4:strcat(info," says, \"You don't look worth it for that money.\"");break;case 5:strcat(info," says, \"It's nothing personal. I'm paid for it!\"");break;case 6:strcat(info," asks \"Did you write a testament? You should.\"");break;case 7:strcat(info, " says, \"You are ");strcat(info, you.your_name);strcat(info, ", aren't you?.\"");break;case 8:strcat(info, " says, \"I suppose that you are ");strcat(info, you.your_name);strcat(info, ". Sorry, if I'm wrong.\"");break;case 9:strcat(info, " says, \"One dead ");strcat(info, you.your_name);strcat(info, ", 500 gold pieces. It's in my contract.\"");break;case 10:strcat(info, " shouts, \"Your time has come!\"");break;case 11:strcat(info," says, \"My job is sometimes very exciting. Sometimes...\"");break;case 12:strcat(info, " says, \"I think I deserve my money.\"");break;case 13:strcat(info," screams, \"Die! I've got more contracts today.\"");break;}break; // end Jozefcase MONS_AGNES: // she is trying to get money and treasureswitch (random2(10)){case 0:strcat(info, " screams, \"Give me all your money!\"");break;case 1:strcat(info, " screams, \"All treasure is mine!\"");break;case 2:strcat(info, " screams, \"You'll never get my money!\"");break;case 3:strcat(info, " grins evilly.");break;case 4:strcat(info," screams, \"Give me everything and get away!\"");break;case 5:strcat(info," says, \"I need a new robe. I'll buy it with your money.\"");break;case 6:strcat(info," screams, \"I want your rings! And amulets! And... EVERYTHING!\"");break;case 7:strcat(info," screams, \"I hate dirty adventurers like you.\"");break;case 8:strcat(info, " says, \"How can you wear that ugly dress?\"");break;case 9:strcat(info, " screams, \"Die, beast!\"");break;}break; // end Agnescase MONS_MAUD: // warrior princess looking for sword "Entarex"switch (random2(11)){case 0:strcat(info, " screams, \"Submit or die!\"");break;case 1:strcat(info, " screams, \"Give me \"Entarex\"!\"");break;case 2:strcat(info," screams, \"If you give me \"Entarex\", I'll let you live!\"");break;case 3:strcat(info, " frowns.");break;case 4:strcat(info, " looks upset.");break;case 5:strcat(info, " screams, \"You can't face my power!\"");break;case 6:strcat(info," screams, \"Give me that sword! Immediately!\"");break;case 7:strcat(info," screams, \"Your life or \"Entarex\"! You must choose.\"");break;case 8:strcat(info, " screams, \"I want it!\"");break;case 9:strcat(info, " screams, \"Die, you thief!\"");break;case 10:// needed at least one in here to tie to the amnesia// scroll reference -- bwrstrcat(info, " asks \"Will you think of me as you die?\"");break;}break; // end Maud// wizard looking for bodyparts as spell componentscase MONS_FRANCIS:switch (random2(15)){case 0:strcat(info," says, \"You've nice eyes. I could use them.\"");break;case 1:strcat(info, " says, \"Excuse me, but I need your head.\"");break;case 2:strcat(info, " says, \"I only need a few of your organs!\"");break;case 3:strcat(info, " ponders the situation.");break;case 4:strcat(info, " looks for a scalpel.");break;case 5:simple_monster_message( monster, " casts a spell",MSGCH_MONSTER_SPELL );strcat(info, "'s hands start to glow with a soft light.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 6:strcat(info, " says, \"This won't hurt a bit.\"");break;case 7:strcat(info, " throws something at you.");break;case 8:strcat(info, " says, \"I want you in my laboratory!\"");break;case 9:strcat(info, " says, \"What about a little dissection?\"");break;case 10:strcat(info," says, \"I have something special for you.\"");break;case 11:strcat(info," screams, \"Don't move! I want to cut off your ear!\"");break;case 12:strcat(info," says, \"What about your heart? Do you need it?\"");break;case 13:strcat(info," says, \"Did you know that corpses are an important natural resource?\"");break;case 14:strcat(info," says, \"Don't worry, I'll only take what I need.\"");break;}break; // end Franciscase MONS_RUPERT: // crazy adventurerswitch (random2(11)){case 0:strcat(info, " says, \"You are a monster, aren't you?\"");break;case 1:strcat(info, " screams, \"Die, monster!\"");break;case 2:strcat(info, " screams, \"Give me the Holy Grail!\"");break;case 3:strcat(info, " screams, \"Red! No, blue!\"");break;case 4:strcat(info, " looks confused.");break;case 5:strcat(info, " looks excited.");break;case 6:strcat(info, " shouts, \"I'm a great and powerful hero!\"");break;case 7:strcat(info," screams, \"Get ready! I'll kill you! Or something like it...\"");break;case 8:strcat(info," says, \"My Mom always said, kill them all.\"");break;case 9:strcat(info," screams, \"You killed all those lovely monsters, you murderer!\"");break;case 10:strcat(info, " screams, \"Hurray!\"");break;}break; // end Rupertcase MONS_NORRIS: // enlighten but crazy manswitch (random2(24)){case 0:strcat(info, " sings \"Hare Rama, Hare Krishna!\"");break;case 1:strcat(info, " smiles at you.");break;case 2:strcat(info," says, \"After death you'll find inner peace.\"");break;case 3:strcat(info," says, \"Life is just suffering. I'll help you.\"");break;case 4:strcat(info, " is surrounded with aura of peace.");break;case 5:strcat(info, " looks very balanced.");break;case 6:strcat(info, " says, \"Don't resist. I'll do it for you.\"");break;case 7:strcat(info, " screams, \"Enter NIRVANA! Now!\"");break;case 8:strcat(info, " says, \"Death is just a liberation!\"");break;case 9:strcat(info," says, \"Feel free to die. It's great thing.\"");break;case 10:strcat(info, " says, \"OHM MANI PADME HUM!\"");break;case 11:strcat(info, " mumbles some mantras.");msg_type = MSGCH_MONSTER_SPELL;break;case 12:strcat(info, " says, \"Breathe deeply.\"");break;case 13:strcat(info, " screams, \"Love! Eternal love!\"");break;case 14:strcat(info," screams, \"Peace! I bring you eternal peace!\"");break;case 15:strcat(info," sighs \"Enlightenment is such responsibility.\"");break;case 16:strcat(info, " looks relaxed.");break;case 17:strcat(info, " screams, \"Free your soul! Die!\"");break;case 18:strcat(info, " screams, \"Blow your mind!\"");break;case 19:strcat(info," says, \"The Orb is only a myth. Forget about it.\"");break;case 20:strcat(info, " says, \"It's all maya.\"");break;case 21:strcat(info, " says, \"Drop out!\"");break;case 22:strcat(info," sings, \"Peace now, freedom now! Peace now, freedom now!\"");break;case 23:strcat(info, " says, \"This is called Combat Meditation.\"");break;}break; // end Norriscase MONS_MARGERY: // powerful sorceress, guarding the ORBswitch (random2(22)){case 0:strcat(info, " says, \"You are dead.\"");break;case 1:strcat(info, " looks very self-confident.");break;case 2:strcat(info, " screams, \"You must be punished!\"");break;case 3:strcat(info, " screams, \"You can't withstand my power!\"");break;case 4:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, " is surrounded with aura of power.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 5:strcat(info, "'s eyes start to glow with a red light.");break;case 6:strcat(info,"'s eyes start to glow with a green light.");break;case 7:strcat(info, "'s eyes start to glow with a blue light.");break;case 8:strcat(info, " screams, \"All trespassers must die!\"");break;case 9:strcat(info, " says, \"Die!\"");break;case 10:strcat(info, " screams, \"You'll have to get past me!\"");break;case 11:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, " becomes transparent for a moment.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 12:strcat(info, " gestures.");msg_type = MSGCH_MONSTER_SPELL;break;case 13:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat(info, "'s hands start to glow.");msg_type = MSGCH_MONSTER_ENCHANT;break;case 14:strcat(info, " screams, \"Ergichanteg reztahaw!\"");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel really bad.", MSGCH_WARN);return (true);
if (match)line = line.substr(pos + 1);}
case 15:strcat(info, " screams, \"You are doomed!\"");break;case 16:strcat(info, " screams, \"Nothing can help you.\"");break;case 17:strcat(info, " screams, \"Death is my middle name!\"");break;case 18:strcat(info, " gestures.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel doomed.", MSGCH_WARN);return (true);case 19:strcat(info, " gestures.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel weakened.", MSGCH_WARN);return (true);case 20:strcat(info, " throws some purple powder towards you.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel cursed.", MSGCH_WARN);return (true);case 21:strcat(info," screams, \"The ORB is only a tale, but I will kill you anyway!");break;}break; // end Margerycase MONS_IJYB: // twisted goblinswitch (random2(14)){case 0:strcat(info, " screams, \"Die!\"");break;case 1:strcat(info, " screams, \"Me kill you!\"");break;case 2:strcat(info, " screams, \"Me stronger than you!\"");break;case 3:case 4:strcat(info, " grins evilly.");break;case 5:strcat(info, " screams, \"It's all mine!\"");break;case 6:strcat(info, " screams, \"Get away!\"");break;case 7:strcat(info, " screams, \"Level is mine! All mine!\"");break;case 8:strcat(info, " screams, \"I cut your head off!\"");break;case 9:strcat(info, " screams, \"I dance on your bones!\"");break;case 10:strcat(info, " screams, \"Me very upset!\"");break;case 11:strcat(info, " screams, \"You nasty! Big nasty!\"");break;case 12:strcat(info, " screams, \"No! No, no, no, no!\"");break;case 13:strcat(info, " screams, \"I no like you!\"");break;}break; // end IJYB
mpr(line.c_str(), msg_type);}
case MONS_BLORK_THE_ORC: // unfriendly orcswitch (random2(21)){case 0:strcat(info, " screams, \"I don't like you!\"");break;case 1:strcat(info, " screams, \"I'm going to kill you!\"");break;case 2:strcat(info," screams, \"I'm much stronger than you!\"");break;case 3:case 4:strcat(info, " grins evilly.");break;case 5:strcat(info, " frowns.");break;case 6:case 7:case 8:case 9:strcat(info, " looks angry.");break;case 10:strcat(info," screams, \"I'll eat your brain! And then I'll vomit it back up!\"");break;case 11:strcat(info," screams, \"You are the ugliest creature I've ever seen!\"");break;case 12:strcat(info, " screams, \"I'll cut your head off!\"");break;case 13:strcat(info, " screams, \"I'll break your legs!\"");break;case 14:strcat(info, " screams, \"I'll break your arms!\"");break;case 15:strcat(info," screams, \"I'll crush all your ribs! One by one!\"");break;case 16:strcat(info," screams, \"I'll make a cloak from your skin!\"");break;case 17:strcat(info," screams, \"I'll decorate my home with your organs!\"");break;case 18:strcat(info, " screams, \"Die!\"");break;case 19:strcat(info," screams, \"I'll cover the dungeon with your blood!\"");break;case 20:strcat(info, " screams, \"I'll drink your blood! Soon!\"");break;}break; // end Blorkcase MONS_EROLCHA: // ugly ogreswitch (random2(11)){case 0:strcat(info, " tries to grin evilly.");break;case 1:strcat(info, " screams, \"Eat!\"");break;case 2:strcat(info, " screams, \"Stand! Erolcha hit you!\"");break;case 3:strcat(info, " screams, \"Blood!\"");break;case 4:strcat(info, " screams, \"Erolcha kill you!\"");break;case 5:strcat(info," screams, \"Erolcha crush your head!\"");break;case 6:strcat(info, " roars.");break;case 7:strcat(info, " growls.");break;case 8:strcat(info, " screams, \"Lunch!\"");break;case 9:strcat(info, " screams, \"Erolcha happy to kill you!\"");break;case 10:strcat(info, " screams, \"Erolcha angry!\"");break;}break; // end Erolchacase MONS_URUG: // orc hired to kill youswitch (random2(11)){case 0:strcat(info, " grins evilly.");break;case 1:strcat(info, " screams, \"Die!\"");break;case 2:strcat(info, " screams, \"I'm going to kill you! Now!\"");break;case 3:strcat(info, " screams, \"Blood and destruction!\"");break;case 4:strcat(info," sneers, \"Innocent? I'll kill you anyway.\"");break;case 5:strcat(info," screams, \"I'll get 30 silver pieces for your head!\"");break;case 6:strcat(info, " roars.");break;case 7:strcat(info, " howls with blood-lust.");break;case 8:strcat(info, " screams, \"You are already dead.\"");break;case 9:strcat(info, " says, \"Maybe you aren't ");strcat(info, you.your_name);strcat(info, ". It doesn't matter.\"");break;case 10:strcat(info, " screams, \"I love blood!\"");break;}break; // end Urugcase MONS_SNORG: // trollswitch (random2(16)){case 0:strcat(info, " grins.");break;case 1:case 2:case 3:strcat(info, " smells terrible.");break;case 4:case 5:case 6:strcat(info, " looks very hungry.");break;case 7:strcat(info, " screams, \"Snack!\"");break;case 8:strcat(info, " roars.");break;case 9:strcat(info, " says, \"Food!\"");break;case 10:strcat(info, " screams, \"Snorg hungry!\"");break;case 11:strcat(info, " screams, \"Snorg very, very hungry!\"");case 12:strcat(info, " says, \"Snorg eat you.\"");break;case 13:strcat(info, " says, \"You food?\"");break;case 14:strcat(info, " says, \"Yum, yum.\"");break;case 15:strcat(info, " burps.");break;}break; // end Snorgcase MONS_XTAHUA: // ancient dragonswitch (random2(13)){case 0:strcat(info, " roars, \"DIE, PUNY ONE!\"");break;case 1:strcat(info, " growls, \"YOU BORE ME SO.\"");break;case 2:strcat(info, " rumbles, \"YOU'RE BARELY A SNACK.\"");break;case 3:strcat(info, " roars, \"I HATE BEING BOTHERED!\"");break;case 4:strcat(info, " roars, \"I HOPE YOU'RE TASTY!\"");break;case 5:strcat(info, " roars, \"BAH! BLOODY ADVENTURERS.\"");break;case 6:strcat(info, " roars, \"FACE MY WRATH!\"");break;case 7:strcat(info, " glares at you.");break;case 8:strcat(info," roars, \"COMING HERE WAS YOUR LAST MISTAKE!\"");break;case 9:strcat(info," roars, \"I'VE KILLED HUNDREDS OF ADVENTURERS!\"");break;case 10:case 11:case 12:strcat(info, " roars horribly.");mpr(info, MSGCH_TALK);mpr("You are afraid.", MSGCH_WARN);return (true);}break; // end Xtahuacase MONS_BORIS: // ancient lichswitch (random2(24)){case 0:strcat(info, " says, \"I didn't invite you.\"");break;case 1:strcat(info, " says, \"You can't imagine my power.\"");break;case 2:strcat(info," says, \"Orb? You want the Orb? You'll never get it.\"");break;case 3:strcat(info, " says, \"The world, the flesh, and the devil.\"");break;case 4:strcat(info, " gestures.");break;case 5:strcat(info, " stares at you.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel drained.", MSGCH_WARN);return (true);case 6:strcat(info, " stares at you.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel weakened.", MSGCH_WARN);return (true);case 7:strcat(info, " stares at you.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You feel troubled.", MSGCH_WARN);return (true);case 8:strcat(info, " says \"Magic. You know nothing about it.\"");break;case 9:strcat(info, " says, \"My power is unlimited.\"");break;case 10:strcat(info, " says, \"You can't kill me. I'm immortal.\"");break;case 11:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);mpr("Your equipment suddenly seems to weigh more.", MSGCH_WARN);return (true);case 12:strcat(info," says, \"I know the secret of eternal life. Do you?\"");break;case 13:strcat(info, " says, \"I'll be back.\"");break;case 14:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);canned_msg( MSG_YOU_RESIST );return (true);case 15:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);mpr("Suddenly you are surrounded with a pale green light.", MSGCH_WARN);return (true);case 16:strcat(info, " casts a spell.");mpr(info, MSGCH_MONSTER_SPELL);mpr("You have a terrible headache.", MSGCH_WARN);return (true);case 17:strcat(info," says, \"I know your future. Your future is death.\"");break;case 18:strcat(info, " says, \"Who wants to live forever? Me.\"");break;case 19:strcat(info, " laughs.");break;case 20:strcat(info, " says, \"Join the legion of my servants.\"");break;case 21:strcat(info, " says, \"There's only one solution for you. To die.\"");break;case 22:strcat(info, " says, \"You can never win.\"");break;case 23:simple_monster_message( monster, " casts a spell.",MSGCH_MONSTER_SPELL );strcat( info, " speeds up." );msg_type = MSGCH_MONSTER_ENCHANT;break;}break; // end BORIScase MONS_DEATH_COB:if (one_chance_in(2000)){mpr("The death cob makes a corny joke.", MSGCH_TALK);return (true);}return (false);case MONS_KILLER_KLOWN: // Killer Klown - guess!switch (random2(10)){case 0:strcat(info, " giggles crazily.");break;case 1:strcat(info, " laughs merrily.");break;case 2:strcat(info, " beckons to you.");break;case 3:strcat(info, " does a flip.");break;case 4:strcat(info, " does a somersault.");break;case 5:strcat(info, " smiles at you.");break;case 6:strcat(info, " grins with merry abandon.");break;case 7:strcat(info, " howls with blood-lust!");break;case 8:strcat(info, " pokes out its tongue.");break;case 9:strcat(info, " says, \"Come and play with me!\"");break;}break; // end Killer Klowndefault:strcat(info," says, \"I don't know what to say. It's a bug.\"");break;} // end monster->type - monster type switch} // end defaultmpr(info, msg_type);
place_monster_aux( band_monsters[i], behaviour, target, px, py,lev_mons, extra, false, dur);
id = place_monster_aux( band_monsters[i], behaviour, target, px, py,lev_mons, extra, false, dur);menv[id].flags |= MF_BAND_MEMBER;
std::string do_mon_str_replacements(const std::string msg,const monsters* monster);enum mon_body_shape {MON_SHAPE_HUMANOID,MON_SHAPE_HUMANOID_WINGED,MON_SHAPE_HUMANOID_TAILED,MON_SHAPE_HUMANOID_WINGED_TAILED,MON_SHAPE_CENTAUR,MON_SHAPE_NAGA,MON_SHAPE_QUADRUPED,MON_SHAPE_QUADRUPED_TAILLESS,MON_SHAPE_QUADRUPED_WINGED,MON_SHAPE_BAT,MON_SHAPE_SNAKE, // Including eels and wormsMON_SHAPE_FISH,MON_SHAPE_INSECT,MON_SHAPE_INSECT_WINGED,MON_SHAPE_ARACHNID,MON_SHAPE_CENTIPEDE,MON_SHAPE_SNAIL,MON_SHAPE_PLANT,MON_SHAPE_FUNGUS,MON_SHAPE_ORB,MON_SHAPE_BLOB,MON_SHAPE_MISC};mon_body_shape get_mon_shape(const monsters *mon);mon_body_shape get_mon_shape(const int type);std::string get_mon_shape_str(const monsters *mon);std::string get_mon_shape_str(const int type);std::string get_mon_shape_str(const mon_body_shape shape);
// Replaces the "@foo@" strings in monster shout and monster speak// definitions.std::string do_mon_str_replacements(const std::string in_msg,const monsters* monster){std::string msg = in_msg;description_level_type nocap, cap;if (monster->attitude == ATT_FRIENDLY && player_monster_visible(monster)){nocap = DESC_PLAIN;cap = DESC_PLAIN;msg = replace_all(msg, "@the_something@", "your @the_something@");msg = replace_all(msg, "@The_something@", "Your @The_something@");msg = replace_all(msg, "@the_monster@", "your @the_monster@");msg = replace_all(msg, "@The_monster@", "Your @the_monster@");}else{nocap = DESC_NOCAP_THE;cap = DESC_CAP_THE;}if (see_grid(monster->x, monster->y)){dungeon_feature_type feat = grd[monster->x][monster->y];if (feat < MINMOVE || feat >= NUM_REAL_FEATURES)msg = replace_all(msg, "@surface@", "buggy surface");else if (feat == DNGN_LAVA)msg = replace_all(msg, "@surface@", "lava");else if (feat == DNGN_DEEP_WATER || feat == DNGN_SHALLOW_WATER)msg = replace_all(msg, "@surface@", "water");else if (feat >= DNGN_ALTAR_ZIN && feat < DNGN_BLUE_FOUNTAIN)msg = replace_all(msg, "@surface@", "altar");elsemsg = replace_all(msg, "@surface@", "ground");msg = replace_all(msg, "@feature@", raw_feature_description(feat));}else{msg = replace_all(msg, "@surface@", "buggy unseen surface");msg = replace_all(msg, "@feature@", "buggy unseen feature");}msg = replace_all(msg, "@player_name@", you.your_name);if (player_monster_visible(monster)){std::string something = monster->name(DESC_PLAIN);msg = replace_all(msg, "@something@", something);msg = replace_all(msg, "@a_something@", monster->name(DESC_NOCAP_A));msg = replace_all(msg, "@the_something@", monster->name(nocap));something[0] = toupper(something[0]);msg = replace_all(msg, "@Something@", something);msg = replace_all(msg, "@A_something@", monster->name(DESC_CAP_A));msg = replace_all(msg, "@The_something@", monster->name(cap));}else{msg = replace_all(msg, "@something@", "something");msg = replace_all(msg, "@a_something@", "something");msg = replace_all(msg, "@the_something@", "something");msg = replace_all(msg, "@Something@", "Something");msg = replace_all(msg, "@A_something@", "Something");msg = replace_all(msg, "@The_something@", "Something");}std::string plain = monster->name(DESC_PLAIN);msg = replace_all(msg, "@monster@", plain);msg = replace_all(msg, "@a_monster@", monster->name(DESC_NOCAP_A));msg = replace_all(msg, "@the_monster@", monster->name(nocap));plain[0] = toupper(plain[0]);msg = replace_all(msg, "@Monster@", plain);msg = replace_all(msg, "@A_monster@", monster->name(DESC_CAP_A));msg = replace_all(msg, "@The_monster@", monster->name(cap));msg = replace_all(msg, "@possessive@",mons_pronoun(monster->type, 3));msg = replace_all(msg, "@pronoun@",mons_pronoun(monster->type, 0));msg = replace_all(msg, "@imp_taunt@", imp_taunt_str());msg = replace_all(msg, "@demon_taunt@", demon_taunt_str());static const char * sound_list[] ={"says", // actually S_SILENT"shouts","barks","shouts","roars","screams","bellows","screeches","buzzes","moans","whines","croaks","growls","hisses","breathes", // S_VERY_SOFT"whispers", // S_SOFT"says", // S_NORMAL"shouts", // S_LOUD"screams" // S_VERY_LOUD};if (mons_shouts(monster->type) >= NUM_SHOUTS){mpr("Invalid @says@ type.", MSGCH_DIAGNOSTICS);msg = replace_all(msg, "@says@", "bugilly says");}elsemsg = replace_all(msg, "@says@",sound_list[mons_shouts(monster->type)]);// The proper possessive for a word ending in an "s" is to// put an appostraphe after the "s": "Chris" -> "Chris'",// not "Chris" -> "Chris's". Stupid English language...msg = replace_all(msg, "s's", "s'");return msg;}static mon_body_shape get_ghost_shape(const monsters *mon){const ghost_demon &ghost = *(mon->ghost);switch(ghost.values[GVAL_SPECIES]){case SP_NAGA:return (MON_SHAPE_NAGA);case SP_CENTAUR:return (MON_SHAPE_CENTAUR);case SP_KENKU:return (MON_SHAPE_HUMANOID_WINGED);case SP_RED_DRACONIAN:case SP_WHITE_DRACONIAN:case SP_GREEN_DRACONIAN:case SP_GOLDEN_DRACONIAN:case SP_GREY_DRACONIAN:case SP_BLACK_DRACONIAN:case SP_PURPLE_DRACONIAN:case SP_MOTTLED_DRACONIAN:case SP_PALE_DRACONIAN:case SP_UNK0_DRACONIAN:case SP_UNK1_DRACONIAN:case SP_BASE_DRACONIAN:return (MON_SHAPE_HUMANOID_TAILED);}return (MON_SHAPE_HUMANOID);}mon_body_shape get_mon_shape(const monsters *mon){if (mon->type == MONS_PLAYER_GHOST)return get_ghost_shape(mon);else if (mons_is_zombified(mon))return get_mon_shape(mon->number);elsereturn get_mon_shape(mon->type);}mon_body_shape get_mon_shape(const int type){switch(mons_char(type)){case 'a': // ants and cockroachesreturn(MON_SHAPE_INSECT);case 'b': // bats and butterflysif (type == MONS_BUTTERFLY)return(MON_SHAPE_INSECT_WINGED);elsereturn(MON_SHAPE_BAT);case 'c': // centaursreturn(MON_SHAPE_CENTAUR);case 'd': // draconions and drakesif (mons_genus(type) == MONS_DRACONIAN ||mons_class_flag(type, M_HUMANOID)){if (mons_class_flag(type, M_FLIES))return(MON_SHAPE_HUMANOID_WINGED_TAILED);elsereturn(MON_SHAPE_HUMANOID_TAILED);}else if (mons_class_flag(type, M_FLIES))return(MON_SHAPE_QUADRUPED_WINGED);elsereturn(MON_SHAPE_QUADRUPED);case 'e': // elvesreturn(MON_SHAPE_HUMANOID);case 'f': // fungireturn(MON_SHAPE_FUNGUS);case 'g': // gargoyles, gnolls, goblins and hobgoblinsif (type == MONS_GARGOYLE)return(MON_SHAPE_HUMANOID_WINGED_TAILED);elsereturn(MON_SHAPE_HUMANOID);case 'h': // houndscase 'j': // jackalsreturn(MON_SHAPE_QUADRUPED);case 'k': // killer beesreturn(MON_SHAPE_INSECT_WINGED);case 'l': // lizardsreturn(MON_SHAPE_QUADRUPED);case 'm': // minotaurs, manticores, and snails/slugs/etcif (type == MONS_MINOTAUR)return(MON_SHAPE_HUMANOID);else if (type == MONS_MANTICORE)return(MON_SHAPE_QUADRUPED);elsereturn(MON_SHAPE_SNAIL);case 'n': // necrophages and ghoulsreturn(MON_SHAPE_HUMANOID);case 'o': // orcsreturn(MON_SHAPE_HUMANOID);case 'p': // ghostsif (type != MONS_INSUBSTANTIAL_WISP &&type != MONS_PLAYER_GHOST)return(MON_SHAPE_HUMANOID);case 'q': // quasistsreturn(MON_SHAPE_HUMANOID_TAILED);case 'r': // rodentsreturn(MON_SHAPE_QUADRUPED);case 's': // arachnids and centidpedsif (type == MONS_GIANT_CENTIPEDE)return(MON_SHAPE_CENTIPEDE);elsereturn(MON_SHAPE_ARACHNID);case 'u': // ugly things are humanoid???return(MON_SHAPE_HUMANOID);case 'v': // vortices and elementalsreturn(MON_SHAPE_MISC);case 'w': // wormsreturn(MON_SHAPE_SNAKE);case 'x': // small abominationsreturn(MON_SHAPE_MISC);case 'y': // winged insectsreturn(MON_SHAPE_INSECT_WINGED);case 'z': // small skeletonsif (type == MONS_SKELETAL_WARRIOR)return(MON_SHAPE_HUMANOID);else// constructed type, not enough info to determine shapereturn(MON_SHAPE_MISC);case 'A': // angelic beingsreturn(MON_SHAPE_HUMANOID_WINGED);case 'B': // beetlesreturn(MON_SHAPE_INSECT);case 'C': // giantsreturn(MON_SHAPE_HUMANOID);case 'D': // dragonsif (mons_class_flag(type, M_FLIES))return(MON_SHAPE_QUADRUPED_WINGED);elsereturn(MON_SHAPE_QUADRUPED);case 'E': // effreetsreturn(MON_SHAPE_HUMANOID);case 'F': // frogsreturn(MON_SHAPE_QUADRUPED_TAILLESS);case 'G': // floating eyeballs and orbsreturn(MON_SHAPE_ORB);case 'H': // hippogriffs and griffnsreturn(MON_SHAPE_QUADRUPED_WINGED);case 'I': // ice beastsreturn(MON_SHAPE_QUADRUPED);case 'J': // jellies and jellyfishreturn(MON_SHAPE_BLOB);case 'K': // koboldsreturn(MON_SHAPE_HUMANOID);case 'L': // lichesreturn(MON_SHAPE_HUMANOID);case 'M': // mummiesreturn(MON_SHAPE_HUMANOID);case 'N': // nagasreturn(MON_SHAPE_NAGA);case 'O': // ogresreturn(MON_SHAPE_HUMANOID);case 'P': // plantsreturn(MON_SHAPE_PLANT);case 'Q': // queen insectsif (type == MONS_QUEEN_BEE)return(MON_SHAPE_INSECT_WINGED);elsereturn(MON_SHAPE_INSECT);case 'R': // rakshasa; humanoid?return(MON_SHAPE_HUMANOID);case 'S': // snakesreturn(MON_SHAPE_SNAKE);case 'T': // trollsreturn(MON_SHAPE_HUMANOID);case 'U': // bearsreturn(MON_SHAPE_QUADRUPED_TAILLESS);case 'V': // vampiresreturn(MON_SHAPE_HUMANOID);case 'W': // wraiths, humanoid if not a spectral thingif (type == MONS_SPECTRAL_THING)// constructed type, not enough info to determine shapereturn(MON_SHAPE_MISC);elsereturn(MON_SHAPE_HUMANOID);case 'X': // large abominationsreturn(MON_SHAPE_MISC);case 'Y': // yaks and sheepif (type == MONS_SHEEP)return(MON_SHAPE_QUADRUPED_TAILLESS);elsereturn(MON_SHAPE_QUADRUPED);case 'Z': // constructed type, not enough info to determine shapereturn(MON_SHAPE_MISC);case ';': // Fish and eelsif (type == MONS_ELECTRICAL_EEL)return(MON_SHAPE_SNAKE);elsereturn (MON_SHAPE_FISH);// The various demons, plus some golems and statues. And humanoids.case '1':case '2':case '3':case '4':case '5':case '&':case '8':case '@':// Assume demon has wings if it can fly.bool flies = mons_class_flag(type, M_FLIES);// Assume demon has a tail if it has a sting attack or a// tail slap attack.monsterentry *mon_data = get_monster_data(type);bool tailed = false;for (int i = 0; i < 4; i++)if (mon_data->attack[i].type == AT_STING ||mon_data->attack[i].type == AT_TAIL_SLAP){tailed = true;break;}if (flies && tailed)return(MON_SHAPE_HUMANOID_WINGED_TAILED);else if (flies && !tailed)return(MON_SHAPE_HUMANOID_WINGED);else if (!flies && tailed)return(MON_SHAPE_HUMANOID_TAILED);elsereturn(MON_SHAPE_HUMANOID);}return(MON_SHAPE_MISC);}std::string get_mon_shape_str(const monsters *mon){return get_mon_shape_str(get_mon_shape(mon));}std::string get_mon_shape_str(const int type){return get_mon_shape_str(get_mon_shape(type));}std::string get_mon_shape_str(const mon_body_shape shape){ASSERT(shape >= MON_SHAPE_HUMANOID && shape <= MON_SHAPE_MISC);if (shape < MON_SHAPE_HUMANOID || shape > MON_SHAPE_MISC)return("buggy shape");static const char *shape_names[] ={"humanoid", "winged humanoid", "tailed humanoid","winged tailed humanoid", "centaur", "naga","quadruped", "tailless quadruped", "winged quadruped","bat", "snake", "fish", "insect", "winged insect","arachnid", "centipede", "snail", "plant", "fungus", "orb","blob", "misc"};return (shape_names[shape]);}
void demon_taunt( const monsters *mons ){std::string str = demon_taunt_str();const std::string mon_name = mons->name(DESC_CAP_THE);static const char * sound_list[] ={"says", // actually S_SILENT"shouts","barks","shouts","roars","screams","bellows","screeches","buzzes","moans","whines","croaks","growls","hisses","breathes", // S_VERY_SOFT"whispers", // S_SOFT"says", // S_NORMAL"shouts", // S_LOUD"screams" // S_VERY_LOUD};const char *voice = sound_list[ mons_shouts(mons->type) ];
MF_CREATED_FRIENDLY = 0x01, // no benefit from killingMF_GOD_GIFT = 0x02, // player not penalized by its deathMF_BATTY = 0x04, // flutters like a batMF_JUST_SUMMONED = 0x08, // monster skips next available actionMF_TAKING_STAIRS = 0x10, // is following player through stairs
MF_CREATED_FRIENDLY = 0x01, // no benefit from killingMF_GOD_GIFT = 0x02, // player not penalized by its deathMF_BATTY = 0x04, // flutters like a batMF_JUST_SUMMONED = 0x08, // monster skips next available actionMF_TAKING_STAIRS = 0x10, // is following player through stairs
MF_INTERESTING = 0x20, // Player finds monster interestingMF_SEEN = 0x40, // Player already seen monsterMF_DIVINE_PROTECTION = 0x80, // Monster has divine protection.
MF_INTERESTING = 0x20, // Player finds monster interestingMF_SEEN = 0x40, // Player already seen monsterMF_DIVINE_PROTECTION = 0x80, // Monster has divine protection.
MF_KNOWN_MIMIC = 0x100, // Mimic that has taken a swing at the PC,// or that the player has inspected with ?MF_BANISHED = 0x200, // Monster that has been banished.MF_HARD_RESET = 0x400, // Summoned, should not drop gear on resetMF_CONVERT_ATTEMPT = 0x800, // Orcs only: seen player and was converted// (or not)MF_WAS_IN_VIEW = 0x1000 // Was in view during previous turn
MF_KNOWN_MIMIC = 0x100, // Mimic that has taken a swing at the PC,// or that the player has inspected with ?MF_BANISHED = 0x200, // Monster that has been banished.MF_HARD_RESET = 0x400, // Summoned, should not drop gear on resetMF_CONVERT_ATTEMPT = 0x800, // Orcs only: seen player and was converted// (or not)MF_WAS_IN_VIEW = 0x1000, // Was in view during previous turnMF_BAND_MEMBER = 0x2000 // Created as a member of a band
break;case CMD_TARGET_WIZARD_MAKE_SHOUT:// Maybe we can skip this check...but it can't hurtif (!you.wizard || !in_bounds(moves.tx, moves.ty))break;mid = mgrd[moves.tx][moves.ty];if (mid == NON_MONSTER) // can put in terrain description herebreak;debug_make_monster_shout(&menv[mid]);
// Only one ghost allowed per levelif (mspec.mid == MONS_PLAYER_GHOST){for (int i = 0; i < MAX_MONSTERS; i++)if (menv[i].type == MONS_PLAYER_GHOST&& menv[i].alive()){mpr("Only one player ghost per level allowed, ""and this level already has one.");return;}}// Only one pandemonium lord allowed per level as well.else if (mspec.mid == MONS_PANDEMONIUM_DEMON){for (int i = 0; i < MAX_MONSTERS; i++)if (menv[i].type == MONS_PANDEMONIUM_DEMON&& menv[i].alive()){mpr("Only one Pandemonium lord per level allowed, ""and this level already has one.");return;}}
dgn_place_monster(mspec, you.your_level, x, y, false);
if (!dgn_place_monster(mspec, you.your_level, x, y, false)){mpr("Unable to place monster");return;}// Need to set a name for the player ghostif (mspec.mid == MONS_PLAYER_GHOST){unsigned char mid = mgrd[x][y];if (mid >= MAX_MONSTERS || menv[mid].type != MONS_PLAYER_GHOST){for (mid = 0; mid < MAX_MONSTERS; mid++)if (menv[mid].type == MONS_PLAYER_GHOST&& menv[mid].alive())break;}if (mid >= MAX_MONSTERS){mpr("Couldn't find player ghost, probably going to crash.");more();return;}monsters &mon = menv[mid];ghost_demon ghost;ghost.name = "John Doe";ghost.values.init(0);char class_str[80];mpr( "Make player ghost which class? ", MSGCH_PROMPT );get_input_line( class_str, sizeof( class_str ) );int class_id = get_class_index_by_abbrev(class_str);if (class_id == -1)class_id = get_class_index_by_name(class_str);if (class_id == -1){mpr("No such class, making it a Fighter.");class_id = JOB_FIGHTER;}ghost.values[GVAL_CLASS] = class_id;mon.set_ghost(ghost);ghosts.push_back(ghost);}
#ifdef WIZARDextern void force_monster_shout(monsters* monster);void debug_make_monster_shout(monsters* mon){mpr("Make the monster (S)hout or (T)alk?", MSGCH_PROMPT);char type = (char) getchm(KC_DEFAULT);type = tolower(type);if (type != 's' && type != 't'){canned_msg( MSG_OK );return;}
int num_times = debug_prompt_for_int("How many times? ", false);if (num_times <= 0){canned_msg( MSG_OK );return;}if (type == 's'){if (silenced(mon->x, mon->y))mpr("The monster is silenced and likely won't give any shouts.");if (silenced(you.x_pos, you.y_pos))mpr("You are silenced and likely won't hear any shouts.");for (int i = 0; i < num_times; i++)force_monster_shout(mon);}else{if (mon->invisible())mpr("The monster is invisble and likely won't speak.");if (silenced(you.x_pos, you.y_pos) && !silenced(mon->x, mon->y))mpr("You are silenced but the monster isn't; you will ""probably hear/see nothing.");else if (!silenced(you.x_pos, you.y_pos) && silenced(mon->x, mon->y))mpr("The monster is silenced and likely won't say anything.");else if (silenced(you.x_pos, you.y_pos) && silenced(mon->x, mon->y))mpr("Both you and the monster are silenced, so you likely ""won't hear anything.");for (int i = 0; i< num_times; i++)mons_speaks(mon);}mpr("== Done ==");}#endif
if (!shoutDB){std::string shoutPath = get_savedir_path(SHOUT_DB);std::string shoutText = datafile_path(SHOUT_TXT);check_newer(shoutPath, shoutText, generate_shout_db);shoutPath.erase(shoutPath.length() - 3);if (!(shoutDB = openDB(shoutPath.c_str())))end(1, true, "Failed to open DB: %s", shoutPath.c_str());}if (!speakDB){std::string speakPath = get_savedir_path(SPEAK_DB);std::string speakText = datafile_path(SPEAK_TXT);check_newer(speakPath, speakText, generate_speak_db);speakPath.erase(speakPath.length() - 3);if (!(speakDB = openDB(speakPath.c_str())))end(1, true, "Failed to open DB: %s", speakPath.c_str());}
}std::string getLongDescription(const std::string &key){if (!descriptionDB)return ("");// We have to canonicalize the key (in case the user typed it// in and got the case wrong.)std::string canonical_key = key;lowercase(canonical_key);// Query the DB.datum result = database_fetch(descriptionDB, canonical_key);// Cons up a (C++) string to return. The caller must release it.return std::string((const char *)result.dptr, result.dsize);
static std::vector<std::string> description_txt_paths(){std::vector<std::string> txt_file_names;std::vector<std::string> paths;txt_file_names.push_back("features");txt_file_names.push_back("items");txt_file_names.push_back("monsters");txt_file_names.push_back("spells");for (int i = 0, size = txt_file_names.size(); i < size; i++){std::string name = DESC_TXT_DIR;name += FILE_SEPARATOR;name += txt_file_names[i];name += ".txt";std::string txt_path = datafile_path(name);paths.push_back(txt_path);}return (paths);}static void store_descriptions(const std::string &in, const std::string &out);static void generate_description_db(){std::string db_path = get_savedir_path(DESC_BASE_NAME);std::string full_db_path = get_savedir_path(DESC_DB);std::vector<std::string> txt_paths = description_txt_paths();file_lock lock(get_savedir_path(DESC_BASE_NAME ".lk"), "wb");unlink( full_db_path.c_str() );for (int i = 0, size = txt_paths.size(); i < size; i++)store_descriptions(txt_paths[i], db_path);DO_CHMOD_PRIVATE(full_db_path.c_str());}
///////////////////////////////////////////////////////////////////////////// Internal DB utility functions
static std::string chooseStrByWeight(std::string entry){std::vector<std::string> parts;std::vector<int> weights;std::vector<std::string> lines = split_string("\n", entry, false, true);int total_weight = 0;for (int i = 0, size = lines.size(); i < size; i++){// Skip over multiple blank lines, and leading and trailing// blank lines.while (i < size && lines[i] == "")i++;if (i == size)break;int weight;std::string part = "";if (sscanf(lines[i].c_str(), "w:%d", &weight)){i++;if (i == size)return ("BUG, WEIGHT AT END OF ENTRY");}elseweight = 10;total_weight += weight;while (i < size && lines[i] != ""){part += lines[i++];part += "\n";}trim_string(part);parts.push_back(part);weights.push_back(total_weight);}if (parts.size() == 0)return("BUG, EMPTY ENTRY");int choice = random2(total_weight);std::string str = "";for (int i = 0, size = parts.size(); i < size; i++)if (choice < weights[i])return(parts[i]);return("BUG, NO STRING CHOSEN");}#define MAX_RECURSION_DEPTH 10#define MAX_REPLACEMENTS 100static std::string getRandomizedStr(DBM *database, const std::string &key,const std::string &suffix,int &num_replacements,int recursion_depth = 0){recursion_depth++;if (recursion_depth > MAX_RECURSION_DEPTH){mpr("Too many nested replacements, bailing.", MSGCH_DIAGNOSTICS);return "TOO MUCH RECURSION";}// We have to canonicalize the key (in case the user typed it// in and got the case wrong.)std::string canonical_key = key + suffix;lowercase(canonical_key);// Query the DB.datum result = database_fetch(database, canonical_key);if (result.dsize <= 0){// Try ignoring the suffixcanonical_key = key;lowercase(canonical_key);// Query the DB.result = database_fetch(database, canonical_key);if (result.dsize <= 0)return "";}// Cons up a (C++) string to return. The caller must release it.std::string str = std::string((const char *)result.dptr, result.dsize);str = chooseStrByWeight(str);// Replace any "@foo@" markers that can be found in this database;// those that can't be found are left alone for the caller to deal// with.std::string::size_type pos = str.find("@");while (pos != std::string::npos){num_replacements++;if (num_replacements > MAX_REPLACEMENTS){mpr("Too many string replacements, bailing.", MSGCH_DIAGNOSTICS);return "TOO MANY REPLACEMENTS";}std::string::size_type end = str.find("@", pos + 1);if (end == std::string::npos){mpr("Unbalanced @, bailing.", MSGCH_DIAGNOSTICS);break;}std::string marker_full = str.substr(pos, end - pos + 1);std::string marker = str.substr(pos + 1, end - pos - 1);std::string replacement =getRandomizedStr(database, marker, suffix, num_replacements,recursion_depth);if (replacement == "")// Nothing in database, leave it alone and go onto next @foo@pos = str.find("@", end + 1);else{str.replace(pos, marker_full.length(), replacement);// Start search from pos rather than end + 1, so that if// the replacement contains its own @foo@, we can replace// that too.pos = str.find("@", pos);}} // while (pos != std::string::npos)return str;}/////////////////////////////////////////////////////////////////////////////// Description DB specific functions.std::string getLongDescription(const std::string &key){if (!descriptionDB)return ("");// We have to canonicalize the key (in case the user typed it// in and got the case wrong.)std::string canonical_key = key;lowercase(canonical_key);// Query the DB.datum result = database_fetch(descriptionDB, canonical_key);// Cons up a (C++) string to return. The caller must release it.return std::string((const char *)result.dptr, result.dsize);}static std::vector<std::string> description_txt_paths(){std::vector<std::string> txt_file_names;std::vector<std::string> paths;txt_file_names.push_back("features");txt_file_names.push_back("items");txt_file_names.push_back("monsters");txt_file_names.push_back("spells");/*txt_file_names.push_back("shout");txt_file_names.push_back("speak");*/for (int i = 0, size = txt_file_names.size(); i < size; i++){std::string name = DESC_TXT_DIR;name += FILE_SEPARATOR;name += txt_file_names[i];name += ".txt";std::string txt_path = datafile_path(name);if (!txt_path.empty())paths.push_back(txt_path);}return (paths);}static void generate_description_db(){std::string db_path = get_savedir_path(DESC_BASE_NAME);std::string full_db_path = get_savedir_path(DESC_DB);std::vector<std::string> txt_paths = description_txt_paths();file_lock lock(get_savedir_path(DESC_BASE_NAME ".lk"), "wb");unlink( full_db_path.c_str() );for (int i = 0, size = txt_paths.size(); i < size; i++)store_text_db(txt_paths[i], db_path);DO_CHMOD_PRIVATE(full_db_path.c_str());}/////////////////////////////////////////////////////////////////////////////// Shout DB specific functions.std::string getShoutString(const std::string &monst,const std::string &suffix){int num_replacements = 0;return getRandomizedStr(shoutDB, monst, suffix, num_replacements);}static void generate_shout_db(){std::string db_path = get_savedir_path(SHOUT_BASE_NAME);std::string full_db_path = get_savedir_path(SHOUT_DB);std::string txt_path = datafile_path(SHOUT_TXT);file_lock lock(get_savedir_path(SHOUT_BASE_NAME ".lk"), "wb");unlink( full_db_path.c_str() );store_text_db(txt_path, db_path);DO_CHMOD_PRIVATE(full_db_path.c_str());}/////////////////////////////////////////////////////////////////////////////// Speak DB specific functions.std::string getSpeakString(const std::string &monst){int num_replacements = 0;return getRandomizedStr(speakDB, monst, "", num_replacements);}static void generate_speak_db(){std::string db_path = get_savedir_path(SPEAK_BASE_NAME);std::string full_db_path = get_savedir_path(SPEAK_DB);std::string txt_path = datafile_path(SPEAK_TXT);file_lock lock(get_savedir_path(SPEAK_BASE_NAME ".lk"), "wb");unlink( full_db_path.c_str() );store_text_db(txt_path, db_path);DO_CHMOD_PRIVATE(full_db_path.c_str());}
"<w>Shift-Dir</w> : shoot straight-line beam\n";
"<w>Shift-Dir</w> : shoot straight-line beam\n"#ifdef WIZARD" \n""<h>Wizard targeting comands:</h>\n""<w>F</w>: make target friendly\n""<w>s</w>: force target to shout or speak\n"#endif;