diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-05 06:59:32 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-05 06:59:32 +0000 |
commit | cfc5e8cefc516db7e842518eb5afeff1b5aa46b5 (patch) | |
tree | e4364dcb162bc3c7bea69eacdb495d5f77bdb300 /crawl-ref | |
parent | dc942d2989c077985d1ba2ca9c87801ef58da35f (diff) | |
download | crawl-ref-cfc5e8cefc516db7e842518eb5afeff1b5aa46b5.tar.gz crawl-ref-cfc5e8cefc516db7e842518eb5afeff1b5aa46b5.zip |
Generalize the mechanism for Boris' death message, so that any monster can
potentially have a death message (or a message for when the monster is banished
or a summon runs out of time).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8235 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/docs/monster_speech.txt | 36 | ||||
-rw-r--r-- | crawl-ref/source/dat/database/monspeak.txt | 10 | ||||
-rw-r--r-- | crawl-ref/source/monspeak.cc | 81 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 28 |
4 files changed, 106 insertions, 49 deletions
diff --git a/crawl-ref/docs/monster_speech.txt b/crawl-ref/docs/monster_speech.txt index 17579e9067..bb5ea8ecc2 100644 --- a/crawl-ref/docs/monster_speech.txt +++ b/crawl-ref/docs/monster_speech.txt @@ -92,6 +92,11 @@ carefully constructed monster speech never gets printed, and this documentation also doesn't help you solve the problem, you might want to post a bug report on Dungeon Crawl's SourceForge site [1]. +The exception to the above is when the monster goes away due to dying, being +banished, or a summoned monster being abjured or having it's time run out. In +that case the monster always speaks if the player can see the grid the monster +is on (assuming that there's a speech entry defined for that occasion, of +course). B. A simple example ==================== @@ -386,13 +391,34 @@ and the only hardcoded keywords are "noisy weapon" for weapons with the noises property, and "singing sword" for (who'd have guessed?) the Singing Sword. +Death speech +------------ +You can define messages for the monster to give for when it goes away in three +different manners: + +* If it really died, then the game will look up a speech entry with the + same keys as usual, but with " killed" appended to all the keys. + +* If it was banished, then the game will append " banished" to all the + lookup keys. + +* If the monster was summoned and rather than being killed was abjured or + ran out of time, then the game will append " unsummoned" to all of the + lookup keys. + +The game will always do a lookup in these circumstances if the player can see +the square the monster is on, so if you only want a death message to be given +occasionally then make one of the messages "__NONE" and give it a high weight. + +Of course, if no keys with the given suffix are in the database then the +monster will say nothing in that circumstance. + Special monster speech ---------------------- -Rarely, monster speech will also rely on hard-coded keys, such as -Boris' "return_speech". If such a hard-coded key is changed or removed, -the speech in question will simply not be printed. This may look odd in -the game, but will have no other effect. Sometimes, default messages -will be output instead. +Rarely, monster speech will also rely on hard-coded keys. If such a hard-coded +key is changed or removed, the speech in question will simply not be printed. +This may look odd in the game, but will have no other effect. Sometimes, +default messages will be output instead. God speech ---------- diff --git a/crawl-ref/source/dat/database/monspeak.txt b/crawl-ref/source/dat/database/monspeak.txt index 2ed980020b..b300f636cb 100644 --- a/crawl-ref/source/dat/database/monspeak.txt +++ b/crawl-ref/source/dat/database/monspeak.txt @@ -1245,7 +1245,7 @@ _Boris_rare_ @The_monster@ says @to_foe@, "Join the legion of my servants." %%%% -Boris return_speech +Boris killed @_Boris_return_common_@ @@ -1260,9 +1260,9 @@ _Boris_return_common_ @The_monster@ says @to_foe@, "This isn't over yet!" -@The_monster@ says @to_foe@, "I'll be back!" +@The_monster@ says, "I'll be back!" -@The_monster@ says @to_foe@, "This isn't the end, it's only just beginning!" +@The_monster@ says, "This isn't the end, it's only just beginning!" %%%% _Boris_return_rare_ @@ -1271,6 +1271,10 @@ _Boris_return_rare_ @The_monster@ says @to_foe@, "You cannot defeat me so easily!" @The_monster@ says @to_foe@, "We will meet again!" +%%%% +Boris unsummoned + +@The_monster@ says, "You can't fire me, I quit!" ## END Boris ## %%%% # An adventurer hating competition diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc index 1d9a7c77b6..51496f4b49 100644 --- a/crawl-ref/source/monspeak.cc +++ b/crawl-ref/source/monspeak.cc @@ -267,11 +267,19 @@ static std::string __get_speak_string(const std::vector<std::string> &prefixes, } static std::string _get_speak_string(const std::vector<std::string> &prefixes, - const std::string &key, + std::string key, const monsters *monster, bool no_player, bool no_foe, bool no_foe_name, bool no_god) { + int duration = 1; + if (monster->hit_points <= 0) + key += " killed"; + else if (monster->flags & MF_BANISHED) + key += " banished"; + else if (monster->is_summoned(&duration) && duration <= 0) + key += " unsummoned"; + std::string msg; for (int tries = 0; tries < 10; tries++) { @@ -354,44 +362,55 @@ static bool _polyd_can_speak(const monsters* monster) // Returns true if something is said. bool mons_speaks(const monsters *monster) { - // 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); - } + ASSERT(!invalid_monster_class(monster->type)); + + // Monsters always talk on death, even if invisible/silenced/etc + int duration = -1; + const bool force_speak = !monster->alive() + || !(monster->flags & MF_BANISHED) + || (monster->is_summoned(&duration) && duration <= 0); + + if (!force_speak) + { + // 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); + } + + // 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->pos()) + && get_monster_data(monster->type)->shouts != S_SILENT) + { + if (!one_chance_in(3)) + return (false); + } - // 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->pos()) - && get_monster_data(monster->type)->shouts != S_SILENT) - { - if (!one_chance_in(3)) + // Berserk monsters just want your hide. + if (monster->has_ench(ENCH_BERSERK)) return (false); - } - - // Berserk monsters just want your hide. - if (monster->has_ench(ENCH_BERSERK)) - return (false); - // Monsters in a battle frenzy are likewise occupied. - if (monster->has_ench(ENCH_BATTLE_FRENZY) && !one_chance_in(3)) - return (false); + // Monsters in a battle frenzy are likewise occupied. + if (monster->has_ench(ENCH_BATTLE_FRENZY) && !one_chance_in(3)) + return (false); - // Charmed monsters aren't too expressive. - if (monster->has_ench(ENCH_CHARM) && !one_chance_in(3)) - return (false); + // Charmed monsters aren't too expressive. + if (monster->has_ench(ENCH_CHARM) && !one_chance_in(3)) + return (false); + } std::vector<std::string> prefixes; if (mons_neutral(monster)) { - if (coinflip()) // Neutrals speak half as often. + if (!force_speak && coinflip()) // Neutrals speak half as often. return (false); prefixes.push_back("neutral"); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 6e4d895468..6be24e7ffe 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -996,6 +996,11 @@ void monster_die(monsters *monster, killer_type killer, if (invalid_monster(monster)) return; + // If a monster was banished to the abyss and then killed there, + // then it's death wasn't a banishment. + if (you.level_type == LEVEL_ABYSS) + monster->flags &= ~MF_BANISHED; + if (!silent && _monster_avoided_death(monster, killer, killer_index)) return; @@ -1012,7 +1017,9 @@ void monster_die(monsters *monster, killer_type killer, remove_auto_exclude(monster); int summon_type = 0; - const bool summoned = mons_is_summoned(monster, NULL, &summon_type); + int duration = 0; + const bool summoned = mons_is_summoned(monster, &duration, + &summon_type); const int monster_killed = monster_index(monster); const bool hard_reset = testbits(monster->flags, MF_HARD_RESET); const bool gives_xp = !summoned @@ -1574,17 +1581,18 @@ void monster_die(monsters *monster, killer_type killer, monster->foe = killer_index; } - if (monster->type == MONS_BORIS && monster->foe != MHITNOT && !in_transit) + + if (!silent && !wizard && see_grid(monster->pos())) { - // XXX: Actual blood curse effect for Boris? -- bwr + // Make sure that the monster looks dead. + if (monster->alive() && !in_transit && (!summoned || duration > 0)) + monster->hit_points = -1; + mons_speaks(monster); + } - // Provide the player with an ingame clue to Boris' return. -- bwr - std::string msg = getSpeakString("Boris return_speech"); - if (!msg.empty()) - { - msg = do_mon_str_replacements(msg, monster); - mpr(msg.c_str(), MSGCH_TALK); - } + if (monster->type == MONS_BORIS && !in_transit) + { + // XXX: Actual blood curse effect for Boris? -- bwr // Now that Boris is dead, he's a valid target for monster // creation again. -- bwr |