From: PatR Date: Sat, 25 Feb 2023 15:02:19 +0000 (-0800) Subject: fix #H2694 - egg hatching feedback X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4fd7d51cb2dce5da0ccc4552bbabc06038904883;p=nethack fix #H2694 - egg hatching feedback A bug report from ten and half years ago... If a carried egg hatches, the message is | drops from your pack. and if tame, is followed by |Its cries sound like {mommy,daddy}. The latter was issued even when has no speech capability. Replace "its cries sound like" with "its ing sounds like" for suitable value of . This adds two new monster sounds, MS_BELLOW and MS_CHIRP, also two new sound effect codes, se_chirp and se_croc_bellow. We had MS_SILENT for crocodile. On wikipedia, crocodile is described as the most vocal reptile. Adult males make a load bellowing noise and hatchlings make a chirping noise. This changes crocodile, titanothere, and baluchitherium from MS_SILENT to MS_BELLOW and baby crocodile from MS_SILENT to MS_CHIRP. Chirp might be appropriate for lizards and lizard-like amphibians but I've left those as MS_SILENT. [Noticed but not changed: lizards and lizard-like amphibians aren't flagged as oviparous. Shouldn't they be?] --- diff --git a/include/extern.h b/include/extern.h index 649fbe9bb..3ec710d20 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2601,6 +2601,7 @@ extern void yelp(struct monst *); extern void whimper(struct monst *); extern void beg(struct monst *); extern const char *maybe_gasp(struct monst *); +extern const char *cry_sound(struct monst *); extern int dotalk(void); extern int tiphat(void); #ifdef USER_SOUNDS diff --git a/include/monflag.h b/include/monflag.h index 8e57a5ec0..d04e84227 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -12,49 +12,51 @@ enum ms_sounds { MS_BARK = 1, /* if full moon, may howl */ MS_MEW = 2, /* mews or hisses */ MS_ROAR = 3, /* roars */ - MS_GROWL = 4, /* growls */ - MS_SQEEK = 5, /* squeaks, as a rodent */ - MS_SQAWK = 6, /* squawks, as a bird */ - MS_HISS = 7, /* hisses */ - MS_BUZZ = 8, /* buzzes (killer bee) */ - MS_GRUNT = 9, /* grunts (or speaks own language) */ - MS_NEIGH = 10, /* neighs, as an equine */ - MS_MOO = 11, /* minotaurs, rothes */ - MS_WAIL = 12, /* wails, as a tortured soul */ - MS_GURGLE = 13, /* gurgles, as liquid or through saliva */ - MS_BURBLE = 14, /* burbles (jabberwock) */ - MS_TRUMPET = 15, /* trumpets (elephant) */ - MS_ANIMAL = 15, /* up to here are animal noises */ - /* FIXME? the grunt "speaks own language" case - shouldn't be classified as animal */ - MS_SHRIEK = 16, /* wakes up others */ - MS_BONES = 17, /* rattles bones (skeleton) */ - MS_LAUGH = 18, /* grins, smiles, giggles, and laughs */ - MS_MUMBLE = 19, /* says something or other */ - MS_IMITATE = 20, /* imitates others (leocrotta) */ - MS_WERE = 21, /* lycanthrope in human form */ - MS_ORC = 22, /* intelligent brutes */ - /* from here onward, speech can be comprehended */ - MS_HUMANOID = 23, /* generic traveling companion */ - MS_ARREST = 24, /* "Stop in the name of the law!" (Kops) */ - MS_SOLDIER = 25, /* army and watchmen expressions */ - MS_GUARD = 26, /* "Please drop that gold and follow me." */ - MS_DJINNI = 27, /* "Thank you for freeing me!" */ - MS_NURSE = 28, /* "Take off your shirt, please." */ - MS_SEDUCE = 29, /* "Hello, sailor." (Nymphs) */ - MS_VAMPIRE = 30, /* vampiric seduction, Vlad's exclamations */ - MS_BRIBE = 31, /* asks for money, or berates you */ - MS_CUSS = 32, /* berates (demons) or intimidates (Wiz) */ - MS_RIDER = 33, /* astral level special monsters */ - MS_LEADER = 34, /* your class leader */ - MS_NEMESIS = 35, /* your nemesis */ - MS_GUARDIAN = 36, /* your leader's guards */ - MS_SELL = 37, /* demand payment, complain about shoplifters */ - MS_ORACLE = 38, /* do a consultation */ - MS_PRIEST = 39, /* ask for contribution; do cleansing */ - MS_SPELL = 40, /* spellcaster not matching any of the above */ - MS_BOAST = 41, /* giants */ - MS_GROAN = 42 /* zombies groan */ + MS_BELLOW = 4, /* adult male crocodiles; hatchlings 'chirp' */ + MS_GROWL = 5, /* growls */ + MS_SQEEK = 6, /* squeaks, as a rodent */ + MS_SQAWK = 7, /* squawks, as a bird */ + MS_CHIRP = 8, /* baby crocodile */ + MS_HISS = 9, /* hisses */ + MS_BUZZ = 10, /* buzzes (killer bee) */ + MS_GRUNT = 11, /* grunts (or speaks own language) */ + MS_NEIGH = 12, /* neighs, as an equine */ + MS_MOO = 13, /* minotaurs, rothes */ + MS_WAIL = 14, /* wails, as a tortured soul */ + MS_GURGLE = 15, /* gurgles, as liquid or through saliva */ + MS_BURBLE = 16, /* burbles (jabberwock) */ + MS_TRUMPET = 17, /* trumpets (elephant) */ + MS_ANIMAL = 17, /* up to here are animal noises */ + /* FIXME? the grunt "speaks own language" case above + shouldn't be classified as animal */ + MS_SHRIEK = 18, /* wakes up others */ + MS_BONES = 19, /* rattles bones (skeleton) */ + MS_LAUGH = 20, /* grins, smiles, giggles, and laughs */ + MS_MUMBLE = 21, /* says something or other */ + MS_IMITATE = 22, /* imitates others (leocrotta) */ + MS_WERE = 23, /* lycanthrope in human form */ + MS_ORC = 24, /* intelligent brutes */ + /* from here onward, speech can be comprehended */ + MS_HUMANOID = 25, /* generic traveling companion */ + MS_ARREST = 26, /* "Stop in the name of the law!" (Kops) */ + MS_SOLDIER = 27, /* army and watchmen expressions */ + MS_GUARD = 28, /* "Please drop that gold and follow me." */ + MS_DJINNI = 29, /* "Thank you for freeing me!" */ + MS_NURSE = 30, /* "Take off your shirt, please." */ + MS_SEDUCE = 31, /* "Hello, sailor." (Nymphs) */ + MS_VAMPIRE = 32, /* vampiric seduction, Vlad's exclamations */ + MS_BRIBE = 33, /* asks for money, or berates you */ + MS_CUSS = 34, /* berates (demons) or intimidates (Wiz) */ + MS_RIDER = 35, /* astral level special monsters */ + MS_LEADER = 36, /* your class leader */ + MS_NEMESIS = 37, /* your nemesis */ + MS_GUARDIAN = 38, /* your leader's guards */ + MS_SELL = 39, /* demand payment, complain about shoplifters */ + MS_ORACLE = 40, /* do a consultation */ + MS_PRIEST = 41, /* ask for contribution; do cleansing */ + MS_SPELL = 42, /* spellcaster not matching any of the above */ + MS_BOAST = 43, /* giants */ + MS_GROAN = 44, /* zombies groan */ }; #define MR_FIRE 0x01 /* resists fire */ diff --git a/include/monsters.h b/include/monsters.h index fc99490c1..5bfe2377c 100644 --- a/include/monsters.h +++ b/include/monsters.h @@ -739,14 +739,14 @@ MON("titanothere", S_QUADRUPED, LVL(12, 12, 6, 0, 0), (G_GENO | 2), A(ATTK(AT_CLAW, AD_PHYS, 2, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), - SIZ(2650, 650, MS_SILENT, MZ_LARGE), 0, 0, + SIZ(2650, 650, MS_BELLOW, MZ_LARGE), 0, 0, M1_ANIMAL | M1_THICK_HIDE | M1_NOHANDS | M1_HERBIVORE, M2_HOSTILE | M2_STRONG, M3_INFRAVISIBLE, 13, CLR_GRAY, TITANOTHERE), MON("baluchitherium", S_QUADRUPED, LVL(14, 12, 5, 0, 0), (G_GENO | 2), A(ATTK(AT_CLAW, AD_PHYS, 5, 4), ATTK(AT_CLAW, AD_PHYS, 5, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), - SIZ(3800, 800, MS_SILENT, MZ_LARGE), 0, 0, + SIZ(3800, 800, MS_BELLOW, MZ_LARGE), 0, 0, M1_ANIMAL | M1_THICK_HIDE | M1_NOHANDS | M1_HERBIVORE, M2_HOSTILE | M2_STRONG, M3_INFRAVISIBLE, 15, CLR_GRAY, BALUCHITHERIUM), @@ -2789,7 +2789,7 @@ MON("baby crocodile", S_LIZARD, LVL(3, 6, 7, 0, 0), G_GENO, A(ATTK(AT_BITE, AD_PHYS, 1, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), - SIZ(200, 200, MS_SILENT, MZ_MEDIUM), 0, 0, + SIZ(200, 200, MS_CHIRP, MZ_MEDIUM), 0, 0, M1_SWIM | M1_AMPHIBIOUS | M1_ANIMAL | M1_NOHANDS | M1_CARNIVORE, M2_HOSTILE, 0, 4, CLR_BROWN, BABY_CROCODILE), MON("lizard", S_LIZARD, LVL(5, 6, 6, 10, 0), (G_GENO | 5), @@ -2808,7 +2808,7 @@ MON("crocodile", S_LIZARD, LVL(6, 9, 5, 0, 0), (G_GENO | 1), A(ATTK(AT_BITE, AD_PHYS, 4, 2), ATTK(AT_CLAW, AD_PHYS, 1, 12), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), - SIZ(WT_HUMAN, 400, MS_SILENT, MZ_LARGE), 0, 0, + SIZ(WT_HUMAN, 400, MS_BELLOW, MZ_LARGE), 0, 0, M1_SWIM | M1_AMPHIBIOUS | M1_ANIMAL | M1_THICK_HIDE | M1_NOHANDS | M1_OVIPAROUS | M1_CARNIVORE, M2_STRONG | M2_HOSTILE, 0, 7, CLR_BROWN, CROCODILE), diff --git a/include/sndprocs.h b/include/sndprocs.h index f6e8dca67..b5af8e5a3 100755 --- a/include/sndprocs.h +++ b/include/sndprocs.h @@ -309,33 +309,35 @@ enum sound_effect_entries { se_buzz = 166, se_squeek = 167, se_squawk = 168, - se_squeal = 169, - se_screech = 170, - se_equine_neigh = 171, - se_equine_whinny = 172, - se_equine_whicker = 173, - se_bovine_moo = 174, - se_bovine_bellow = 175, - se_wail = 176, - se_groan = 177, - se_grunt = 178, - se_gurgle = 179, - se_elephant_trumpet = 180, - se_snake_rattle = 181, - se_yelp = 182, - se_jabberwock_burble = 183, - se_shriek = 184, - se_bone_rattle = 185, - se_orc_grunt = 186, - se_avian_screak = 187, - se_paranoid_confirmation = 188, - se_bars_whang = 189, - se_bars_whap = 190, - se_bars_flapp = 191, - se_bars_clink = 192, - se_bars_clonk = 193, - se_boomerang_klonk = 194, - se_bang_weapon_side = 195, + se_chirp = 169, + se_squeal = 170, + se_screech = 171, + se_equine_neigh = 172, + se_equine_whinny = 173, + se_equine_whicker = 174, + se_bovine_moo = 175, + se_bovine_bellow = 176, + se_croc_bellow = 177, + se_wail = 178, + se_groan = 179, + se_grunt = 180, + se_gurgle = 181, + se_elephant_trumpet = 182, + se_snake_rattle = 183, + se_yelp = 184, + se_jabberwock_burble = 185, + se_shriek = 186, + se_bone_rattle = 187, + se_orc_grunt = 188, + se_avian_screak = 189, + se_paranoid_confirmation = 190, + se_bars_whang = 191, + se_bars_whap = 192, + se_bars_flapp = 193, + se_bars_clink = 194, + se_bars_clonk = 195, + se_boomerang_klonk = 196, + se_bang_weapon_side = 197, number_of_se_entries }; diff --git a/src/sounds.c b/src/sounds.c index c4eeca169..54e765746 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -342,7 +342,7 @@ static const char *const h_sounds[] = { "eep", "clatter", "hum", "sizzle", "twitter", "wheeze", "rustle", "honk", "lisp", "yodel", "coo", "burp", "moo", "boom", "murmur", "oink", "quack", "rumble", - "twang", "bellow", "toot", "gargle", "hoot", "warble" + "twang", "toot", "gargle", "hoot", "warble" }; const char * @@ -362,6 +362,9 @@ growl_sound(register struct monst* mtmp) case MS_ROAR: ret = "roar"; break; + case MS_BELLOW: + ret = "bellow"; + break; case MS_BUZZ: ret = "buzz"; break; @@ -580,6 +583,7 @@ maybe_gasp(struct monst* mon) case MS_GRUNT: /* ogres, trolls, gargoyles, one or two others */ case MS_LAUGH: /* leprechaun, gremlin */ case MS_ROAR: /* dragon, xorn, owlbear */ + case MS_BELLOW: /* crocodile */ /* capable of speech but only do so if hero is similar type */ case MS_DJINNI: case MS_VAMPIRE: /* vampire in its own form */ @@ -603,9 +607,55 @@ maybe_gasp(struct monst* mon) return (const char *) 0; } +/* for egg hatching; caller will apply "ing" suffix + [the old message when a carried egg hatches was + "its cries sound like {mommy,daddy}" + regardless of what type of sound--if any--the creature made] */ +const char * +cry_sound(struct monst *mtmp) +{ + const char *ret = 0; + struct permonst *ptr = mtmp->data; + + /* a relatively small subset of MS_ sound values are used by oviparous + species so we don't try to supply something for every MS_ type */ + switch (ptr->msound) { + default: + case MS_SILENT: /* insects, arthropods, worms, sea creatures */ + /* "chitter": have silent critters make some noise + or the mommy/daddy gag when hatching doesn't work */ + ret = (ptr->mlet == S_EEL) ? "gurgle" : "chitter"; + break; + case MS_HISS: /* chickatrice, pyrolisk, snakes */ + ret = "hiss"; + break; + case MS_ROAR: /* baby dragons; have them growl instead of roar */ + /*FALLTHRU*/ + case MS_GROWL: /* (none) */ + ret = "growl"; + break; + case MS_CHIRP: /* adult crocodiles bellow, babies chirp */ + ret = "chirp"; + break; + case MS_BUZZ: /* killer bees */ + ret = "buzz"; + break; + case MS_SQAWK: /* ravens */ + ret = "screech"; + break; + case MS_GRUNT: /* gargoyles */ + ret = "grunt"; + break; + case MS_MUMBLE: /* naga hatchlingss */ + ret = "mumble"; + break; + } + return ret; +} + /* return True if mon is a gecko or seems to look like one (hallucination) */ static boolean -mon_is_gecko(struct monst* mon) +mon_is_gecko(struct monst *mon) { int glyph; @@ -637,9 +687,8 @@ domonnoise(register struct monst* mtmp) /* presumably nearness and sleep checks have already been made */ if (Deaf) return ECMD_OK; - if (is_silent(ptr) - /* shk_chat can handle nonverbal monsters */ - && !mtmp->isshk) + /* shk_chat can handle nonverbal monsters */ + if (is_silent(ptr) && !mtmp->isshk) return ECMD_OK; /* leader might be poly'd; if he can still speak, give leader speech */ @@ -657,6 +706,8 @@ domonnoise(register struct monst* mtmp) || same_race(ptr, &mons[Race_switch])) /* unpoly'd form */ || Hallucination)) msound = MS_HUMANOID; + else if (msound == MS_MOO && !mtmp->mtame) + msound = MS_BELLOW; /* silliness; formerly had a slight chance to interfere with shopping */ else if (Hallucination && mon_is_gecko(mtmp)) msound = MS_SELL; @@ -691,17 +742,18 @@ domonnoise(register struct monst* mtmp) break; case MS_VAMPIRE: { /* vampire messages are varied by tameness, peacefulness, and time of - * night */ + night */ boolean isnight = night(); boolean kindred = (Upolyd && (u.umonnum == PM_VAMPIRE || u.umonnum == PM_VAMPIRE_LEADER)); - boolean nightchild = - (Upolyd && (u.umonnum == PM_WOLF || u.umonnum == PM_WINTER_WOLF - || u.umonnum == PM_WINTER_WOLF_CUB)); - const char *racenoun = - (flags.female && gu.urace.individual.f) - ? gu.urace.individual.f - : (gu.urace.individual.m) ? gu.urace.individual.m : gu.urace.noun; + boolean nightchild = (Upolyd && (u.umonnum == PM_WOLF + || u.umonnum == PM_WINTER_WOLF + || u.umonnum == PM_WINTER_WOLF_CUB)); + const char *racenoun = (flags.female && gu.urace.individual.f) + ? gu.urace.individual.f + : (gu.urace.individual.m) + ? gu.urace.individual.m + : gu.urace.noun; if (mtmp->mtame) { if (kindred) { @@ -738,14 +790,14 @@ domonnoise(register struct monst* mtmp) }; int vampindex; - if (kindred) + if (kindred) { verbl_msg = "This is my hunting ground that you dare to prowl!"; - else if (gy.youmonst.data == &mons[PM_SILVER_DRAGON] - || gy.youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) { + } else if (gy.youmonst.data == &mons[PM_SILVER_DRAGON] + || gy.youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) { /* Silver dragons are silver in color, not made of silver */ Sprintf(verbuf, "%s! Your silver sheen does not frighten me!", - gy.youmonst.data == &mons[PM_SILVER_DRAGON] + (gy.youmonst.data == &mons[PM_SILVER_DRAGON]) ? "Fool" : "Young Fool"); verbl_msg = verbuf; @@ -771,11 +823,14 @@ domonnoise(register struct monst* mtmp) pline("%s throws back %s head and lets out a blood curdling %s!", Monnam(mtmp), mhis(mtmp), (ptr == &mons[PM_HUMAN_WERERAT]) ? "shriek" : "howl"); - Soundeffect(((ptr == &mons[PM_HUMAN_WERERAT]) ? se_scream : se_canine_howl), 80); + Soundeffect((ptr == &mons[PM_HUMAN_WERERAT]) ? se_scream + : se_canine_howl, + 80); wake_nearto(mtmp->mx, mtmp->my, 11 * 11); - } else + } else { pline_msg = "whispers inaudibly. All you can make out is \"moon\"."; + } break; case MS_BARK: if (flags.moonphase == FULL_MOON && night()) { @@ -788,8 +843,7 @@ domonnoise(register struct monst* mtmp) else if (mtmp->mtame && EDOG(mtmp)->hungrytime > gm.moves + 1000) pline_msg = "yips."; else { - if (mtmp->data - != &mons[PM_DINGO]) /* dingos do not actually bark */ + if (ptr != &mons[PM_DINGO]) /* dingos do not actually bark */ pline_msg = "barks."; } } else { @@ -864,8 +918,18 @@ domonnoise(register struct monst* mtmp) } break; case MS_MOO: - Soundeffect((mtmp->mpeaceful ? se_bovine_moo : se_bovine_bellow), 80); - pline_msg = mtmp->mpeaceful ? "moos." : "bellows!"; + Soundeffect(se_bovine_moo, 80); + pline_msg = "moos."; + break; + case MS_BELLOW: + Soundeffect((ptr->mlet == S_QUADRUPED) ? se_bovine_bellow + : se_croc_bellow, + 80); + pline_msg = "bellows!"; + break; + case MS_CHIRP: + Soundeffect(se_chirp, 60); + pline_msg = "chirps."; break; case MS_WAIL: Soundeffect(se_sad_wailing, 60); @@ -1004,13 +1068,11 @@ domonnoise(register struct monst* mtmp) and they never verbalize step 2 so we don't either */ verbl_msg = (gnomeplan == 1) ? "Phase one, collect underpants." : "Phase three, profit!"; - } - else { + } else { verbl_msg = "Many enter the dungeon, and few return to the sunlit lands."; } - } - else + } else switch (monsndx(ptr)) { case PM_HOBBIT: /* 3.7: the 'complains' message used to be given if the @@ -1040,7 +1102,8 @@ domonnoise(register struct monst* mtmp) if (SYSOPT_SEDUCE) { if (ptr->mlet != S_NYMPH - && could_seduce(mtmp, &gy.youmonst, (struct attack *) 0) == 1) { + && (could_seduce(mtmp, &gy.youmonst, (struct attack *) 0) + == 1)) { (void) doseduce(mtmp); break; } @@ -1872,7 +1935,7 @@ struct soundeffect_automapping { }; static const struct soundeffect_automapping - se_mappings_init[number_of_se_entries] = { + se_mappings_init[number_of_se_entries] = { { se_zero_invalid, "" }, { se_faint_splashing, "faint_splashing" }, { se_crackling_of_hellfire, "crackling_of_hellfire" }, diff --git a/src/timeout.c b/src/timeout.c index 80fdd6d07..a4b7e74d4 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1012,8 +1012,10 @@ hatch_egg(anything *arg, long timeout) You_see("%s %s out of your pack!", monnambuf, locomotion(mon->data, "drop")); if (yours) { - pline("%s cries sound like \"%s%s\"", + pline("%s %s %s like \"%s%s\"", siblings ? "Their" : "Its", + ing_suffix(cry_sound(mon)), + (is_silent(mon->data) || Deaf) ? "seems" : "sounds", flags.female ? "mommy" : "daddy", egg->spe ? "." : "?"); } else if (mon->data->mlet == S_DRAGON && !Deaf) { SetVoice(mon, 0, 80, 0);