diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-12-29 04:38:32 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-12-29 04:38:32 +0000 |
commit | 3ccb84a86f21de5797a5a2480711233fb38ea9d5 (patch) | |
tree | f9179f655db052cf8b002614cde1ac8bfd706891 /crawl-ref/source | |
parent | 8f4023a8f1efa5f683e92244341149b6cc46a338 (diff) | |
download | crawl-ref-3ccb84a86f21de5797a5a2480711233fb38ea9d5.tar.gz crawl-ref-3ccb84a86f21de5797a5a2480711233fb38ea9d5.zip |
Changes to monster spell messages:
* If the monster's casting would be affected by Silence then attempt to
indicate that the monster is using words.
* Allow for different messages for targeted spells vs untargeted spells.
* Provide some special messages for the Animate Dead spell.
* Don't let sphinxes gesture or point.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8007 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/dat/database/monspell.txt | 177 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 8 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 73 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 178 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 23 |
5 files changed, 334 insertions, 125 deletions
diff --git a/crawl-ref/source/dat/database/monspell.txt b/crawl-ref/source/dat/database/monspell.txt index bbf76a8b83..821186e6ff 100644 --- a/crawl-ref/source/dat/database/monspell.txt +++ b/crawl-ref/source/dat/database/monspell.txt @@ -1,12 +1,68 @@ +# This file contains the messages used to "announce" a spell, like +# "The wizard mumbles some strange words." The messages are looked +# up in the following order by the following keys: +# +# 1) The name of the spell being cast: +# a) If being cast by a wizard or priest monster with arms, first try +# with the suffix "real". +# b) If being cast by a monster of normal or higher intelligence with arms, +# try with the suffix "gestures". +# c) Next, try without any suffix. +# 2) The name of the monster's type. +# 3) The name of the monster's species. +# 4) The name of the monster's genus. +# 5) "priest" if the monster is a priest type, "wizard" if it's a wizard type, +# or "demon" if it's demonic. +# +# For 2 to 5, if the spell has a target it will first add the suffix +# "targeted" to the lookup key before trying without the suffix. +# +# For all lookups, if the monster is unseen by the player it will add the +# prefix "unseen" to the key, or if the player or monster is silenced +# it will prefix "silent" to the key (if the monster is both unseen and +# unheard no message is ever given). If using the prefix "silent" gives +# no results it will try again without the prefix, assuming that the +# spell has no sound component. +# +# To give no message use the string "__NONE", and to skip the current +# lookup method and move onto the next one use the string "__NEXT". + ##################################################### # Individual spells. ##################################################### %%%% +unseen Animate Dead cast real + +You hear @something@ calling out to the dead. +%%%% +Animate Dead cast real + +@The_monster@ gestures at the surounding area while chanting. + +@The_monster@ throws @possessive@ @arms@ wide while chanting. +%%%% +Animate Dead cast gestures + +@The_monster@ gestures at the surounding. + +@The_monster@ throws @possessive@ @arms@ wide. +%%%% +Symbol of Torment cast + +@The_monster@ calls on the powers of Hell! +%%%% +unseen Symbol of Torment cast + +@The_something@ calls on the powers of Hell! +##################################################### +# Individual innate spells (breathing and spitting). +##################################################### +%%%% Acid Splash cast @The_monster@ spits acid at @target@. %%%% -Acid Splash cast unseen +unseen Acid Splash cast You hear a spitting sound. %%%% @@ -14,7 +70,7 @@ Draconian Breath cast @The_monster@ breathes @beam@ at @target@. %%%% -Draconian Breath cast unseen +unseen Draconian Breath cast You hear a roar. %%%% @@ -22,7 +78,7 @@ Poison Splash cast @The_monster@ spits poison at @target@. %%%% -Poison Splash cast unseen +unseen Poison Splash cast You hear a spitting sound. %%%% @@ -30,57 +86,56 @@ Sticky Flame Splash cast @The_monster@ spits sticky flame at @target@. %%%% -Sticky Flame Splash cast unseen +unseen Sticky Flame Splash cast You hear a spitting sound. +######################################################################## +# Individual monsters +######################################################################## %%%% -Symbol of Torment cast +Geryon cast -@The_monster@ calls on the powers of Hell! +@The_monster@ winds a great silver horn. %%%% -Symbol of Torment cast unseen +unseen Geryon cast -@The_something@ calls on the powers of Hell! -##################################################### -# Priest and wizard casting messages. -##################################################### +You hear a weird and mournful sound. %%%% -priest cast +giant orange brain cast -@The_monster@ prays. +@The_monster@ pulsates. +%%%% +orb of fire cast -@The_monster@ mumbles some strange prayers. +@The_monster@ glows yellow. -@The_monster@ utters an invocation. -%%%% -priest cast unseen +@The_monster@ glows bright magenta. -You hear some strange, mumbled prayers. -%%%% -wizard cast +@The_monster@ glows deep purple. -@The_monster@ gestures wildly. +@The_monster@ glows red. + +@The_monster@ emits a lurid red light. +%%%% +# Sphinxes can't gesture or point. +sphinx cast @The_monster@ mumbles some strange words. @The_monster@ casts a spell. -%%%% -wizard cast unseen - -You hear some strange, mumbled words. ######################################################################## -# Monster genus and species messages. +# Monster species and genus messages. ######################################################################## %%%% -demon cast +dragon cast targeted -@The_monster@ gestures. +@The_monster@ breathes @beam@ at @target@. %%%% dragon cast -@The_monster@ breathes @beam@ at @target@. +@The_monster@ USED A NON-TARGETED DRAGON SPELL. Please file a bug report. %%%% -dragon cast unseen +unseen dragon cast You hear a roar. %%%% @@ -90,38 +145,66 @@ curse skull cast @The_monster@ casts a spell. %%%% -curse skull cast unseen +unseen curse skull cast You hear the clattering of teeth. %%%% +giant eyeball cast targeted + +@The_monster@ gazes at @target@. +%%%% giant eyeball cast -@The_monster@ gazes. -######################################################################## -# Individual monsters -######################################################################## +@The_monster@ looks around. +###################################################### +# Generic priest, wizard and demonic casting messages. +###################################################### %%%% -Geryon cast +priest cast targeted -@The_monster@ winds a great silver horn. +@The_monster@ prays against @target@. + +@The_monster@ mumbles some strange prayers against @target@. + +@The_monster@ utters an invocation against @target@. %%%% -Geryon cast unseen +priest cast -You hear a weird and mournful sound. +@The_monster@ prays. + +@The_monster@ mumbles some strange prayers. + +@The_monster@ utters an invocation. %%%% -giant orange brain cast +unseen priest cast -@The_monster@ pulsates. +You hear some strange, mumbled prayers. %%%% -orb of fire cast +wizard cast targeted -@The_monster@ glows yellow. +@The_monster@ gestures at @target@ while chanting. -@The_monster@ glows bright magenta. +@The_monster@ points at @target@ and mumbles some strange words. -@The_monster@ glows deep purple. +@The_monster@ casts a spell at @target@. +%%%% +wizard cast -@The_monster@ glows red. +@The_monster@ gestures wildly while chanting. -@The_monster@ emits a lurid red light. +@The_monster@ mumbles some strange words. + +@The_monster@ casts a spell. +%%%% +unseen wizard cast + +You hear some strange, mumbled words. +%%%% +demon cast targeted + +@The_monster@ gestures at @target@. +%%%% +demon cast + +@The_monster@ gestures. %%%% diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 520d7f08b1..4c11d2a6e0 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -310,6 +310,8 @@ public: bool *can_plural = NULL) const = 0; virtual std::string foot_name(bool plural, bool *can_plural = NULL) const = 0; + virtual std::string arm_name(bool plural, + bool *can_plural = NULL) const = 0; virtual bool fumbles_attack(bool verbose = true) = 0; @@ -387,6 +389,7 @@ public: virtual bool paralysed() const = 0; virtual bool cannot_move() const = 0; + virtual bool cannot_act() const = 0; virtual bool confused() const = 0; virtual bool caught() const = 0; virtual bool asleep() const { return (false); } @@ -1034,6 +1037,7 @@ public: std::string conj_verb(const std::string &verb) const; std::string hand_name(bool plural, bool *can_plural = NULL) const; std::string foot_name(bool plural, bool *can_plural = NULL) const; + std::string arm_name(bool plural, bool *can_plural = NULL) const; bool fumbles_attack(bool verbose = true); bool cannot_fight() const; @@ -1094,6 +1098,7 @@ public: bool paralysed() const; bool cannot_move() const; + bool cannot_act() const; bool confused() const; bool caught() const; bool backlit(bool check_haloed = true) const; @@ -1104,8 +1109,6 @@ public: void awake(); void check_awaken(int disturbance); - bool cannot_act() const; - bool can_throw_large_rocks() const; int armour_class() const; @@ -1426,6 +1429,7 @@ public: std::string conj_verb(const std::string &verb) const; std::string hand_name(bool plural, bool *can_plural = NULL) const; std::string foot_name(bool plural, bool *can_plural = NULL) const; + std::string arm_name(bool plural, bool *can_plural = NULL) const; bool fumbles_attack(bool verbose = true); bool cannot_fight() const; diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 6e3aad8da5..e90a4d7809 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -5233,6 +5233,36 @@ std::string monsters::foot_name(bool plural, bool *can_plural) const return (str); } +std::string monsters::arm_name(bool plural, bool *can_plural) const +{ + mon_body_shape shape = get_mon_shape(this); + + if (shape > MON_SHAPE_NAGA) + return hand_name(plural, can_plural); + + if (can_plural != NULL) + *can_plural = true; + + std::string str; + switch(mons_genus(type)) + { + case MONS_NAGA: + case MONS_DRACONIAN: str = "scaled arm"; break; + + case MONS_MUMMY: str = "bandaged wrapped arm"; break; + + case MONS_SKELETAL_WARRIOR: + case MONS_LICH: str = "bony arm"; break; + + default: str = "arm"; break; + } + + if (plural) + str = pluralise(str); + + return (str); +} + int monsters::id() const { return (type); @@ -7903,6 +7933,49 @@ std::string do_mon_str_replacements(const std::string &in_msg, msg = replace_all(msg, "@possessive@", monster->pronoun(PRONOUN_NOCAP_POSSESSIVE)); + // Body parts. + bool can_plural = false; + std::string part_str = monster->hand_name(false, &can_plural); + + msg = replace_all(msg, "@hand@", part_str); + msg = replace_all(msg, "@Hand@", upcase_first(part_str)); + + if (!can_plural) + part_str = "NO PLURAL HANDS"; + else + part_str = monster->hand_name(true); + + msg = replace_all(msg, "@hands@", part_str); + msg = replace_all(msg, "@Hands@", upcase_first(part_str)); + + can_plural = false; + part_str = monster->arm_name(false, &can_plural); + + msg = replace_all(msg, "@arm@", part_str); + msg = replace_all(msg, "@Arm@", upcase_first(part_str)); + + if (!can_plural) + part_str = "NO PLURAL ARMS"; + else + part_str = monster->arm_name(true); + + msg = replace_all(msg, "@arms@", part_str); + msg = replace_all(msg, "@Arms@", upcase_first(part_str)); + + can_plural = false; + part_str = monster->foot_name(false, &can_plural); + + msg = replace_all(msg, "@foot@", part_str); + msg = replace_all(msg, "@Foot@", upcase_first(part_str)); + + if (!can_plural) + part_str = "NO PLURAL FOOT"; + else + part_str = monster->foot_name(true); + + msg = replace_all(msg, "@feet@", part_str); + msg = replace_all(msg, "@Feet@", upcase_first(part_str)); + // Replace with "you are" for atheists. msg = replace_all(msg, "@god_is@", _replace_god_name(true, false)); msg = replace_all(msg, "@God_is@", _replace_god_name(true, true)); diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index ca82b57e37..ecdfc8e4ca 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -549,24 +549,26 @@ void mons_cast_noise(monsters *monster, bolt &pbolt, spell_type spell_cast) // Draining breath is silent. force_silent = true; - const bool unseen = !you.can_see(monster); - const bool silent = silenced(monster->pos()) || force_silent; + const bool unseen = !you.can_see(monster); + const bool silent = silenced(monster->pos()) || force_silent; + const bool no_silent = mons_class_flag(monster->type, M_SPELL_NO_SILENT); - if (unseen && silent) + if (unseen && silent || silent && no_silent) return; const unsigned int flags = get_spell_flags(real_spell); const bool priest = mons_class_flag(monster->type, M_PRIEST); const bool wizard = mons_class_flag(monster->type, M_ACTUAL_SPELLS); - const bool innate = !(priest || wizard) || (flags & SPFLAG_INNATE); + const bool innate = !(priest || wizard || no_silent) + || (flags & SPFLAG_INNATE); int noise; if(silent || (innate - && !mons_class_flag(monster->type, M_SPELL_NO_SILENT - | M_NOISY_SPELLS) - && !(flags & SPFLAG_NOISY))) + && !mons_class_flag(monster->type, M_NOISY_SPELLS) + && !(flags & SPFLAG_NOISY) + && mons_genus(monster->type) != MONS_DRAGON)) { noise = 0; } @@ -579,78 +581,101 @@ void mons_cast_noise(monsters *monster, bolt &pbolt, spell_type spell_cast) } const std::string cast_str = " cast"; - std::string suffix; - if (silent) - suffix = " silent"; - else if (unseen) - suffix = " unseen"; - - std::string key; - // First try the individual spell. - key = spell_title(real_spell) + cast_str; - std::string msg = getSpeakString(key + suffix); + const std::string spell_name = spell_title(real_spell); + const mon_body_shape shape = get_mon_shape(monster); - if (msg.empty() && silent) - msg = getSpeakString(key); + std::vector<std::string> key_list; - // Second, try the individual monster. - if (msg.empty()) + // First try the spells name. + if (shape <= MON_SHAPE_NAGA && !innate) { - key = mons_type_name(monster->type, DESC_PLAIN); - key += cast_str; - msg = getSpeakString(key + suffix); - - if (msg.empty() && silent) - msg = getSpeakString(key); + if (priest || wizard) + key_list.push_back(spell_name + cast_str + " real"); + if (mons_intel(monster) >= I_NORMAL) + key_list.push_back(spell_name + cast_str + " gestures"); } + key_list.push_back(spell_name + cast_str); - // Third, try generic priest or wizard messages. - if (msg.empty() && !innate) - { - if (priest) - key = "priest"; - else - key = "wizard"; + const unsigned int num_spell_keys = key_list.size(); - key += cast_str; - msg = getSpeakString(key + suffix); + // Next the monster type name, then species name, then genus name. + key_list.push_back(mons_type_name(monster->type, DESC_PLAIN) + cast_str); + key_list.push_back(mons_type_name(mons_species(monster->type), DESC_PLAIN) + + cast_str); + key_list.push_back(mons_type_name(mons_genus(monster->type), DESC_PLAIN) + + cast_str); - if (msg.empty() && silent) - msg = getSpeakString(key); - } + // Last, generic wizard, priest or demon. + if (wizard) + key_list.push_back("wizard" + cast_str); + else if (priest) + key_list.push_back("priest" + cast_str); + else if (mons_is_demon(monster->type)) + key_list.push_back("demon" + cast_str); - // Fourth, try the monster's species. - if (msg.empty()) + // For targeted spells, try with the targeted suffix first. + if (in_bounds(pbolt.target) && pbolt.target != monster->pos() + && (flags & SPFLAG_TARGETING_MASK)) { - key = mons_type_name(mons_species(monster->type), DESC_PLAIN); - key += cast_str; - msg = getSpeakString(key + suffix); - - if (msg.empty() && silent) - msg = getSpeakString(key); + for (unsigned int i = key_list.size() - 1; i >= num_spell_keys; i--) + { + std::string str = key_list[i] + " targeted"; + key_list.insert(key_list.begin() + i, str); + } } - // Fifth, try the monster's genus. - if (msg.empty()) + std::string prefix; + if (silent) + prefix = "silent "; + else if (unseen) + prefix = "unseen "; + + std::string msg; + for (unsigned int i = 0; i < key_list.size(); i++) { - key = mons_type_name(mons_genus(monster->type), DESC_PLAIN); - key += cast_str; - msg = getSpeakString(key + suffix); + const std::string key = key_list[i]; - if (msg.empty() && silent) - msg = getSpeakString(key); - } + msg = getSpeakString(prefix + key); + if (msg == "__NONE") + { + msg = ""; + break; + } + else if (msg == "__NEXT") + { + msg = ""; + if (i < num_spell_keys) + i = num_spell_keys - 1; + else if (ends_with(key, " targeted")) + i++; + continue; + } + else if (!msg.empty()) + break; - // Lastly, maybe it's a demon. - if (msg.empty() && mons_is_demon(monster->type)) - { - key = "demon"; - key += cast_str; - msg = getSpeakString(key + suffix); + // If we got no message and we're using the silent prefix, then + // try again without the prefix. + if (prefix != "silent") + continue; - if (msg.empty() && silent) - msg = getSpeakString(key); + msg = getSpeakString(key); + if (msg == "__NONE") + { + msg = ""; + break; + } + else if (msg == "__NEXT") + { + msg = ""; + if (i < num_spell_keys) + i = num_spell_keys - 1; + else if (ends_with(key, " targeted")) + i++; + continue; + } + else if (!msg.empty()) + break; } if (msg.empty()) @@ -662,9 +687,17 @@ void mons_cast_noise(monsters *monster, bolt &pbolt, spell_type spell_cast) return; } + ///////////////////// + // We have a message. + ///////////////////// + std::string target = "something"; - if (pbolt.target == you.pos()) + if (!(flags & SPFLAG_TARGETING_MASK) || !in_bounds(pbolt.target)) + target = "NO TARGET"; + else if (pbolt.target == you.pos()) target = "you"; + else if (pbolt.target == monster->pos()) + target = monster->pronoun(PRONOUN_REFLEXIVE); else if (see_grid(pbolt.target)) { int midx = mgrd(pbolt.target); @@ -684,13 +717,16 @@ void mons_cast_noise(monsters *monster, bolt &pbolt, spell_type spell_cast) // fired. std::string beam_name; if (pbolt.flavour <= BEAM_NONE - || pbolt.flavour >= NUM_BEAMS + || pbolt.flavour > BEAM_LAST_REAL || pbolt.name.empty()) { beam_name = "INVALID BEAM"; } - else if (pbolt.type == 0 || pbolt.name[0] == '0') + else if (pbolt.type == 0 || pbolt.type == ' ' || pbolt.name[0] == '0' + || pbolt.is_enchantment()) + { beam_name = "INVISIBLE BEAM"; + } else beam_name = pbolt.get_short_name(); @@ -707,16 +743,6 @@ void mons_cast_noise(monsters *monster, bolt &pbolt, spell_type spell_cast) return; } - if (msg.find(" roar") != std::string::npos) - noise = get_shout_noise_level(S_ROAR); - else if (msg.find(" breathes") != std::string::npos) - { - shout_type type = mons_shouts(monster->type); - if(type == S_SILENT) - type = S_ROAR; - noise = get_shout_noise_level(type); - } - // noisy() returns true if the player heard the noise. if (noisy(noise, monster->pos()) || !unseen) mons_speaks_msg(monster, msg, chan); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 526e6358eb..4fc49dc56a 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6295,6 +6295,29 @@ std::string player::foot_name(bool plural, bool *can_plural) const return str; } +std::string player::arm_name(bool plural, bool *can_plural) const +{ + if (transform_changed_physiology()) + return hand_name(plural, can_plural); + + if (can_plural != NULL) + *can_plural = true; + + std::string str = "arm"; + + if (player_genus(GENPC_DRACONIAN) || you.species == SP_NAGA) + str = "scaled arm"; + else if (you.species == SP_KENKU) + str = "feathered arm"; + else if (you.species == SP_MUMMY) + str = "bandaged wrapped arm"; + + if (plural) + str = pluralise(str); + + return (str); +} + int player::id() const { return (-1); |