diff --git a/crawl-ref/source/dat/database/shout.txt b/crawl-ref/source/dat/database/shout.txt index a4c90280531..4ee53f4ade1 100644 --- a/crawl-ref/source/dat/database/shout.txt +++ b/crawl-ref/source/dat/database/shout.txt @@ -222,6 +222,14 @@ __SQUEAK seen SOUND:@The_monster@ squeaks loudly. %%%% +__RASPBERRY unseen + +SOUND:You hear a loud raspberry. +%%%% +__RASPBERRY seen + +SOUND:@The_monster@ blows a very loud wet raspberry. +%%%% ############################################ # End of default shouts ############################################ diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt index 021086b90e1..0314847c435 100644 --- a/crawl-ref/source/dat/descript/monsters.txt +++ b/crawl-ref/source/dat/descript/monsters.txt @@ -737,6 +737,12 @@ A fast, gas-filled floating spore released by a ballistomycete when it senses a threat. After seeking out its foe, the spore will explode, damaging anything caught in the blast and further confusing living creatures. %%%% +balloon yak + +A cartoonish caricature of a living beast, twisted together by some insane street +performer and given life with a breath of chaos. On death will create a rapid +expulsion of air followed by a slower release of clouds of chaos. +%%%% balrug A huge and very powerful demon, wreathed in fire and shadows. diff --git a/crawl-ref/source/dat/descript/quotes.txt b/crawl-ref/source/dat/descript/quotes.txt index f80b9279ffb..c0295db6945 100644 --- a/crawl-ref/source/dat/descript/quotes.txt +++ b/crawl-ref/source/dat/descript/quotes.txt @@ -2689,6 +2689,14 @@ arcanist %%%% +balloon yak + +“I suppose even a simple slogan can be twisted into whatever shape we want, + like a balloon animal – we can even make it loop back around on itself, + becoming a noose. In the end, the measure of who we are can be seen in + the shapes of our balloon animals.” + -Neal Shusterman +%%%% basilisk “Be thou like the imperial Basilisk diff --git a/crawl-ref/source/dat/mons/balloon-yak.yaml b/crawl-ref/source/dat/mons/balloon-yak.yaml new file mode 100644 index 00000000000..ea744f173a6 --- /dev/null +++ b/crawl-ref/source/dat/mons/balloon-yak.yaml @@ -0,0 +1,19 @@ +name: "balloon yak" +glyph: {char: "Y", colour: red} +flags: [flies, herd, unbreathing, no_skeleton, no_zombie, no_gen_derived] +xp_mult: 15 +genus: yak +will: 100 +attacks: + - {type: gore, damage: 42} +hd: 18 +hp_10x: 1200 +ac: 12 +ev: 4 +spells: balloon_yak +has_corpse: false +shout: raspberry +intelligence: animal +size: large +shape: quadruped +tile_variance: mod diff --git a/crawl-ref/source/melee-attack.cc b/crawl-ref/source/melee-attack.cc index af63a021c61..6ceb491a9d8 100644 --- a/crawl-ref/source/melee-attack.cc +++ b/crawl-ref/source/melee-attack.cc @@ -2279,6 +2279,11 @@ void melee_attack::set_attack_verb(int damage) attack_verb = "spit"; verb_degree = "like the proverbial pig"; } + else if (defender->type == MONS_BALLOON_YAK) + { + attack_verb = "pop"; + verb_degree = "like a balloon"; + } else if (defender_genus == MONS_CRAB && Options.has_fake_lang(flang_t::grunt)) { diff --git a/crawl-ref/source/mgen-enum.h b/crawl-ref/source/mgen-enum.h index 4643ea6653b..a20f0097afd 100644 --- a/crawl-ref/source/mgen-enum.h +++ b/crawl-ref/source/mgen-enum.h @@ -137,6 +137,7 @@ enum band_type BAND_SLIMES_AND_MASTER, BAND_ELEPHANTS_AND_MASTER, BAND_SPHINXES, + BAND_BALLOON_YAKS, NUM_BANDS // always last }; diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc index 8a84803875a..3bac3ab8cda 100644 --- a/crawl-ref/source/mon-death.cc +++ b/crawl-ref/source/mon-death.cc @@ -27,6 +27,7 @@ #include "dgn-overview.h" #include "english.h" #include "env.h" +#include "evoke.h" // Windblast death effect #include "fineff.h" #include "god-abil.h" #include "god-blessing.h" @@ -3112,6 +3113,31 @@ item_def* monster_die(monster& mons, killer_type killer, treant_release_fauna(mons); else if (mons.type == MONS_PHARAOH_ANT && real_death) _pharaoh_ant_bind_souls(&mons); + else if (mons.type == MONS_BALLOON_YAK && real_death && !mons.pacified()) + { + if (you.can_see(mons)) + { + mprf(MSGCH_WARN, "The %s ruptures with a %s and chaos begins " + "spilling from the puncture!", mons.name(DESC_PLAIN).c_str(), + silenced(you.pos()) ? "rush of air" : "loud pop"); + } + else if (!silenced(you.pos())) + mprf(MSGCH_WARN, "You hear a loud pop and a rush of air!"); + + // Wind blast their foe or otherwise you. The real spell power + // would knock you well out of reach of the clouds, 50 is about right. + auto foe = mons.get_foe(); + wind_blast(&mons, 50, foe ? foe->pos() : you.pos()); + + map_cloud_spreader_marker *marker = + new map_cloud_spreader_marker(mons.pos(), CLOUD_CHAOS, 8, + 40 + random2(25), LOS_DEFAULT_RANGE, + 8, &mons); + // Start the cloud at radius 1, regardless of the speed of the killing blow + marker->speed_increment -= you.time_taken; + env.markers.add(marker); + env.markers.clear_need_activate(); + } else if (!mons.is_summoned() && mummy_curse_power(mons.type) > 0) { // TODO: set attacker better? (Player attacker is handled by checking diff --git a/crawl-ref/source/mon-enum.h b/crawl-ref/source/mon-enum.h index 549e9f73457..cff95578a65 100644 --- a/crawl-ref/source/mon-enum.h +++ b/crawl-ref/source/mon-enum.h @@ -293,6 +293,7 @@ enum shout_type S_LOUD_ROAR, // dragons, &c. loud! S_RUSTLE, // books S_SQUEAK, // rats and similar + S_RASPBERRY, // balloon yaks NUM_SHOUTS, // Loudness setting for shouts that are only defined in dat/shout.txt diff --git a/crawl-ref/source/mon-pick-data.h b/crawl-ref/source/mon-pick-data.h index fd1f024f7a2..fa298e4137c 100644 --- a/crawl-ref/source/mon-pick-data.h +++ b/crawl-ref/source/mon-pick-data.h @@ -779,6 +779,7 @@ POP_DEPTHS, { 1, 5, 150, RISE, MONS_CURSE_TOE }, { 1, 5, 515, FLAT, MONS_TENTACLED_MONSTROSITY }, { 1, 5, 89, FALL, MONS_ELECTRIC_GOLEM }, + { 1, 5, 42, FLAT, MONS_BALLOON_YAK }, { 1, 5, 42, FLAT, MONS_ORB_OF_FIRE }, }, #if TAG_MAJOR_VERSION == 34 diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc index a6dad1ec757..d6bc32538ba 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -1783,6 +1783,11 @@ static const map bands_by_leader = { { MONS_YAKTAUR_CAPTAIN, { {2}, {{ BAND_YAKTAURS, {2, 5}, true }}}}, { MONS_YAKTAUR, { {2}, {{ BAND_YAKTAURS, {2, 5} }}}}, { MONS_DEATH_YAK, { {}, {{ BAND_DEATH_YAKS, {2, 6} }}}}, + { MONS_BALLOON_YAK, { {2, 0, []() { + return branch_has_monsters(you.where_are_you) + || !vault_mon_types.empty(); + }}, {{ BAND_BALLOON_YAKS, {1, 2} }, + { BAND_RANDOM_SINGLE, {1, 3} }}}}, { MONS_OGRE_MAGE, { {}, {{ BAND_OGRE_MAGE, {4, 8} }}}}, { MONS_LODUL, { {}, {{ BAND_OGRES, {6, 10}, true }}}}, { MONS_BALRUG, { {0, 0, []() { return !player_in_hell(); }}, @@ -2205,6 +2210,7 @@ static const map> band_membership = { { BAND_ALLIGATOR, {{{MONS_ALLIGATOR, 1}}}}, { BAND_JELLYFISH, {{{MONS_FORMLESS_JELLYFISH, 1}}}}, { BAND_DEATH_YAKS, {{{MONS_DEATH_YAK, 1}}}}, + { BAND_BALLOON_YAKS, {{{MONS_BALLOON_YAK, 1}}}}, { BAND_GREEN_RATS, {{{MONS_RIVER_RAT, 1}}}}, { BAND_BRAIN_WORMS, {{{MONS_BRAIN_WORM, 1}}}}, { BAND_BLINK_FROGS, {{{MONS_BLINK_FROG, 1}}}}, diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index b5e66159d72..7a9eabcda82 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1324,6 +1324,7 @@ int get_shout_noise_level(const shout_type shout) case S_SOFT: return 6; case S_LOUD: + case S_RASPBERRY: return 10; case S_LOUD_ROAR: case S_VERY_LOUD: @@ -1354,11 +1355,12 @@ static bool _shout_fits_monster(monster_type mc, int shout) switch (shout) { - // Bees, books, cherubs and two-headed ogres never fit. + // Bees, books, cherubs, two-headed ogres and balloon yaks never fit. case S_SHOUT2: case S_BUZZ: case S_CHERUB: case S_RUSTLE: + case S_RASPBERRY: // The beast cannot speak. case S_DEMON_TAUNT: return false; @@ -4835,6 +4837,7 @@ string do_mon_str_replacements(const string &in_msg, const monster& mons, "roars", "rustles", // dubious "squeaks", + "wetly raspberries", // balloon yak "buggily says", // NUM_SHOUTS "breathes", // S_VERY_SOFT "whispers", // S_SOFT diff --git a/crawl-ref/source/monster-type.h b/crawl-ref/source/monster-type.h index e3fd5f33be4..3624dec65cf 100644 --- a/crawl-ref/source/monster-type.h +++ b/crawl-ref/source/monster-type.h @@ -95,6 +95,9 @@ enum monster_type // env.mons[].type #endif MONS_YAK, MONS_DEATH_YAK, +#if TAG_MAJOR_VERSION > 34 + MONS_BALLOON_YAK, +#endif MONS_CATOBLEPAS, MONS_ELEPHANT, MONS_DIRE_ELEPHANT, @@ -1330,6 +1333,7 @@ enum monster_type // env.mons[].type MONS_POLTERGEIST, // player species dummy MONS_VAMPIRE_BLOODPRINCE, MONS_REVENANT, // player species dummy + MONS_BALLOON_YAK, #endif NUM_MONSTERS, // used for polymorph diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index cee49f7e390..edfa8f3209b 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -2381,7 +2381,8 @@ string monster::foot_name(bool plural, bool *can_plural) const str = "paw"; else if (ch == 'l' || ch == 'D') str = "talon"; - else if (type == MONS_YAK || type == MONS_DEATH_YAK) + else if (type == MONS_YAK || type == MONS_DEATH_YAK + || type == MONS_BALLOON_YAK) str = "hoof"; else if (ch == 'H') { diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index 508ee5d7f3d..897a20fc96b 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -306,6 +306,10 @@ polar_bear MONS_POLAR_BEAR dream_sheep MONS_DREAM_SHEEP yak MONS_YAK death_yak MONS_DEATH_YAK +balloon_yak1 MONS_BALLOON_YAK +balloon_yak2 +balloon_yak3 +balloon_yak4 catoblepas MONS_CATOBLEPAS elephant MONS_ELEPHANT elephant_dire MONS_DIRE_ELEPHANT diff --git a/crawl-ref/source/rltiles/mon/animals/balloon_yak1.png b/crawl-ref/source/rltiles/mon/animals/balloon_yak1.png new file mode 100644 index 00000000000..e57c4c760fb Binary files /dev/null and b/crawl-ref/source/rltiles/mon/animals/balloon_yak1.png differ diff --git a/crawl-ref/source/rltiles/mon/animals/balloon_yak2.png b/crawl-ref/source/rltiles/mon/animals/balloon_yak2.png new file mode 100644 index 00000000000..b4f9da71390 Binary files /dev/null and b/crawl-ref/source/rltiles/mon/animals/balloon_yak2.png differ diff --git a/crawl-ref/source/rltiles/mon/animals/balloon_yak3.png b/crawl-ref/source/rltiles/mon/animals/balloon_yak3.png new file mode 100644 index 00000000000..df6cf645e53 Binary files /dev/null and b/crawl-ref/source/rltiles/mon/animals/balloon_yak3.png differ diff --git a/crawl-ref/source/rltiles/mon/animals/balloon_yak4.png b/crawl-ref/source/rltiles/mon/animals/balloon_yak4.png new file mode 100644 index 00000000000..3c14b707f1a Binary files /dev/null and b/crawl-ref/source/rltiles/mon/animals/balloon_yak4.png differ diff --git a/crawl-ref/source/shout.cc b/crawl-ref/source/shout.cc index dbd04fe3255..9ec2865a3d7 100644 --- a/crawl-ref/source/shout.cc +++ b/crawl-ref/source/shout.cc @@ -70,6 +70,7 @@ static const map default_msg_keys = { { S_LOUD_ROAR, "__LOUD_ROAR" }, { S_RUSTLE, "__RUSTLE" }, { S_SQUEAK, "__SQUEAK" }, + { S_RASPBERRY, "__RASPBERRY" }, }; /**