From 7e2b5b7c0f3125942a23449a13d7a86180249473 Mon Sep 17 00:00:00 2001 From: mumra Date: Mon, 30 Sep 2024 08:33:41 +0100 Subject: [PATCH] Strolling Stone: new monster A craggy, mossy beast inhabiting the early dungeon. When it attacks it will shed plant-based detritus in the form of toadstools and lichen. A mid-range addition to D that requires careful handling and frustrates the player by littering the battlefield with obstacles. The tile is a mash-up of the "orb statue", "guardian golem", "stone_mossy2", with a dash of the old glowing mold. --- crawl-ref/source/dat/descript/monsters.txt | 8 ++ .../source/dat/mons/strolling-stone.yaml | 19 ++++ crawl-ref/source/describe.cc | 1 + crawl-ref/source/melee-attack.cc | 9 +- crawl-ref/source/mon-death.cc | 4 + crawl-ref/source/mon-enum.h | 2 + crawl-ref/source/mon-pick-data.h | 1 + crawl-ref/source/mon-place.cc | 2 + crawl-ref/source/monster-type.h | 2 + crawl-ref/source/rltiles/dc-mon.txt | 1 + .../rltiles/mon/nonliving/strolling_stone.png | Bin 0 -> 2946 bytes crawl-ref/source/spl-summoning.cc | 93 ++++++++++++++++++ crawl-ref/source/spl-summoning.h | 1 + 13 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 crawl-ref/source/dat/mons/strolling-stone.yaml create mode 100644 crawl-ref/source/rltiles/mon/nonliving/strolling_stone.png diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt index 5c10ebeebfb..567a3fbb1b6 100644 --- a/crawl-ref/source/dat/descript/monsters.txt +++ b/crawl-ref/source/dat/descript/monsters.txt @@ -2869,6 +2869,14 @@ strange machine A strange mechanical contraption, all hisses and pops. Shadows seem to dance across its reflective surface. %%%% +strolling stone + +They say a rolling stone gathers no moss; this may be true, but when moving at +more of a sauntering pace they gather all kinds of detritus. A craggy beast +shuffling through the dungeon covered in moss, lichen, and fungus. + +When struck it will shed lichen and mushrooms around itself. +%%%% sun demon A demonic figure shining with the heat and fury of a fallen star. diff --git a/crawl-ref/source/dat/mons/strolling-stone.yaml b/crawl-ref/source/dat/mons/strolling-stone.yaml new file mode 100644 index 00000000000..106fde66a8c --- /dev/null +++ b/crawl-ref/source/dat/mons/strolling-stone.yaml @@ -0,0 +1,19 @@ +name: "strolling stone" +glyph: {char: "9", colour: lightgreen} +flags: [speaks, no_skeleton, unblindable] +xp_mult: 15 +resists: {elec: 1, petrify: 1} +genus: golem +holiness: [nonliving] +will: 20 +attacks: + - {type: hit, flavour: shed, damage: 16} +hd: 5 +hp_10x: 290 +ac: 5 +ev: 2 +shout: moan +intelligence: human +speed: 10 +size: large +shape: humanoid diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 2c6186f8f39..1f18e24bbbf 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -5169,6 +5169,7 @@ static string _flavour_base_desc(attack_flavour flavour) { AF_BOMBLET, "deploy bomblets" }, { AF_AIRSTRIKE, "open air damage" }, { AF_TRICKSTER, "drain, daze, or confuse" }, + { AF_SHED, "sheds detritus from its body" }, { AF_PLAIN, "" }, }; diff --git a/crawl-ref/source/melee-attack.cc b/crawl-ref/source/melee-attack.cc index 3d70d05ce29..9fa08947e4c 100644 --- a/crawl-ref/source/melee-attack.cc +++ b/crawl-ref/source/melee-attack.cc @@ -3770,6 +3770,7 @@ void melee_attack::mons_apply_attack_flavour() } break; } + case AF_SLEEP: if (!coinflip()) break; @@ -3788,7 +3789,6 @@ void melee_attack::mons_apply_attack_flavour() defender->put_to_sleep(attacker, random_range(3, 5) * BASELINE_DELAY); break; - case AF_ALEMBIC: { if (needs_message) @@ -3822,6 +3822,13 @@ void melee_attack::mons_apply_attack_flavour() if (--attacker->as_monster()->number == 0) alembic_brew_potion(*attacker->as_monster()); } + + case AF_SHED: + { + if (!defender->is_firewood()) + summon_detritus(*attacker->as_monster(), defender->pos()); + break; + } break; case AF_BOMBLET: diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc index 2dec3a22aa1..eaaae154cd5 100644 --- a/crawl-ref/source/mon-death.cc +++ b/crawl-ref/source/mon-death.cc @@ -3101,6 +3101,10 @@ item_def* monster_die(monster& mons, killer_type killer, bennu_revive_fineff::schedule(mons.pos(), revives, att, mons.foe, duel, gozag_bribe); } + // XX: if the strolling stone *was* an illusion/summoned, unsummon its + // illusory sheddings too... + else if (mons.type == MONS_STROLLING_STONE) + summon_detritus(mons, mons.pos(), true); } if (mons_is_tentacle_head(mons_base_type(mons))) diff --git a/crawl-ref/source/mon-enum.h b/crawl-ref/source/mon-enum.h index af98798506b..c9f1ce12196 100644 --- a/crawl-ref/source/mon-enum.h +++ b/crawl-ref/source/mon-enum.h @@ -155,6 +155,7 @@ enum attack_flavour AF_BOMBLET, AF_AIRSTRIKE, AF_TRICKSTER, + AF_SHED, }; // Non-spell "summoning" types to give to monster::mark_summoned(), or @@ -180,6 +181,7 @@ enum mon_summon_type MON_SUMM_WPN_REAP, // Reaping brand reaping MON_SUMM_CACOPHONY, // Poltergeist ability MON_SUMM_THRALL, // Vampiric thralls + MON_SUMM_DETRITUS, // Strolling stone shedding }; #include "mon-flags.h" diff --git a/crawl-ref/source/mon-pick-data.h b/crawl-ref/source/mon-pick-data.h index 2760b1d74ab..49441d0d60b 100644 --- a/crawl-ref/source/mon-pick-data.h +++ b/crawl-ref/source/mon-pick-data.h @@ -120,6 +120,7 @@ static const vector population[] = { 7, 11, 200, PEAK, MONS_HORNET }, { 7, 11, 350, PEAK, MONS_WYVERN }, { 8, 12, 800, PEAK, MONS_YAK }, + { 8, 12, 200, PEAK, MONS_STROLLING_STONE}, { 8, 15, 75, SEMI, MONS_WOLF_LICHEN }, { 8, 14, 350, PEAK, MONS_ACID_DRAGON }, { 8, 14, 600, PEAK, MONS_TWO_HEADED_OGRE }, diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc index 6f3874012b9..c29ed77e55a 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -1410,6 +1410,8 @@ static monster* _place_monster_aux(const mgen_data &mg, const monster *leader, } else if (mons_is_child_tentacle(mg.cls)) blame_prefix = "attached to "; + else if (mg.cls == MONS_TOADSTOOL || mg.cls == MONS_WOLF_LICHEN) + blame_prefix = "shed by "; else blame_prefix = "created by "; diff --git a/crawl-ref/source/monster-type.h b/crawl-ref/source/monster-type.h index 87e22743d33..561b4c59dcd 100644 --- a/crawl-ref/source/monster-type.h +++ b/crawl-ref/source/monster-type.h @@ -675,6 +675,7 @@ enum monster_type // env.mons[].type MONS_HELLFIRE_MORTAR, MONS_SPLINTERFROST_BARRICADE, MONS_SHADOW_TURRET, + MONS_STROLLING_STONE, #endif // Demons: @@ -1337,6 +1338,7 @@ enum monster_type // env.mons[].type MONS_REVENANT, // player species dummy MONS_ROCK_FISH, MONS_WOLF_LICHEN, + MONS_STROLLING_STONE, #endif NUM_MONSTERS, // used for polymorph diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index 34cafffed77..d0699466e41 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -640,6 +640,7 @@ gargoyle MONS_GARGOYLE war_gargoyle MONS_WAR_GARGOYLE molten_gargoyle MONS_MOLTEN_GARGOYLE %rim 0 +strolling_stone MONS_STROLLING_STONE nargun MONS_NARGUN %rim 1 diff --git a/crawl-ref/source/rltiles/mon/nonliving/strolling_stone.png b/crawl-ref/source/rltiles/mon/nonliving/strolling_stone.png new file mode 100644 index 0000000000000000000000000000000000000000..8d72c8864d126a467d4d6ed7dccf9d119b3f0183 GIT binary patch literal 2946 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 == agent.mid) + { + if (mi->type == MONS_WOLF_LICHEN) + count_lichen++; + else if (mi->type == MONS_TOADSTOOL) + count_shroom++; + } + } + + int num_shroom = 0; + int num_lichen = 0; + const int num_total = is_death ? 4 : 2; + + // Create up to 4 max of each type + for (int n=0; nget_ench(ENCH_SUMMON).duration : 0; + + if (num_shroom > 0) + { + for (int n=0; n 0) + { + for (int n=0; n