Skip to content

Commit

Permalink
Strolling Stone: new monster
Browse files Browse the repository at this point in the history
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 pre-Lair addition to D that requires careful handling and frustrates
the player by littering the battlefield with obstacles.
  • Loading branch information
chucksellick committed Feb 18, 2025
1 parent ea3e224 commit 976d416
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 1 deletion.
6 changes: 6 additions & 0 deletions crawl-ref/source/dat/descript/monsters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2883,6 +2883,12 @@ 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; but a strolling one gathers all
kinds of detritus. A craggy, statuesque beast, shuffling through the dungeon
covered in moss, lichen, and mushrooms.
%%%%
sun demon

A demonic figure shining with the heat and fury of a fallen star.
Expand Down
18 changes: 18 additions & 0 deletions crawl-ref/source/dat/mons/strolling-stone.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: "strolling stone"
glyph: {char: "9", colour: lightgreen}
flags: [speaks, no_skeleton]
resists: {elec: 1, petrify: 1}
genus: golem
holiness: [nonliving]
will: 20
attacks:
- {type: hit, flavour: shed, damage: 13}
hd: 5
hp_10x: 290
ac: 5
ev: 2
shout: moan
intelligence: human
speed: 10
size: large
shape: humanoid
1 change: 1 addition & 0 deletions crawl-ref/source/describe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5170,6 +5170,7 @@ static string _flavour_base_desc(attack_flavour flavour)
{ AF_AIRSTRIKE, "open air damage" },
{ AF_TRICKSTER, "drain, daze, or confuse" },
{ AF_VEX, "cause vexation" },
{ AF_SHED, "sheds detritus from its body" },
{ AF_PLAIN, "" },
};

Expand Down
9 changes: 8 additions & 1 deletion crawl-ref/source/melee-attack.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3776,6 +3776,7 @@ void melee_attack::mons_apply_attack_flavour()
}
break;
}

case AF_SLEEP:
if (!coinflip())
break;
Expand All @@ -3794,7 +3795,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)
Expand Down Expand Up @@ -3828,6 +3828,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:
Expand Down
4 changes: 4 additions & 0 deletions crawl-ref/source/mon-death.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3150,6 +3150,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)))
Expand Down
1 change: 1 addition & 0 deletions crawl-ref/source/mon-enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ enum attack_flavour
AF_TRICKSTER,
AF_SILVER,
AF_VEX,
AF_SHED,
};

// Non-spell "summoning" types to give to monster::mark_summoned(), or
Expand Down
1 change: 1 addition & 0 deletions crawl-ref/source/mon-pick-data.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ static const vector<pop_entry> population[] =
{ 6, 9, 1000, PEAK, MONS_BULLFROG },
{ 6, 10, 500, PEAK, MONS_WIGHT },
{ 6, 10, 350, PEAK, MONS_STEAM_DRAGON },
{ 6, 10, 200, PEAK, MONS_STROLLING_STONE},
{ 6, 11, 500, PEAK, MONS_KOBOLD_BRIGAND },
{ 6, 12, 600, PEAK, MONS_ORC_WARRIOR },
{ 7, 11, 500, PEAK, MONS_KILLER_BEE },
Expand Down
2 changes: 2 additions & 0 deletions crawl-ref/source/mon-place.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,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 ";

Expand Down
2 changes: 2 additions & 0 deletions crawl-ref/source/monster-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ enum monster_type // env.mons[].type
MONS_HELLFIRE_MORTAR,
MONS_SPLINTERFROST_BARRICADE,
MONS_SHADOW_TURRET,
MONS_STROLLING_STONE,
#endif

// Demons:
Expand Down Expand Up @@ -1341,6 +1342,7 @@ enum monster_type // env.mons[].type
MONS_ROCK_FISH_SCHOOL,
MONS_SILVER_FISH,
MONS_WOLF_LICHEN,
MONS_STROLLING_STONE,
#endif

NUM_MONSTERS, // used for polymorph
Expand Down
1 change: 1 addition & 0 deletions crawl-ref/source/rltiles/dc-mon.txt
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,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

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions crawl-ref/source/spl-summoning.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2706,6 +2706,89 @@ bool summon_swarm_clone(const monster& agent, coord_def target_pos)
return false;
}

bool summon_detritus(const monster& agent, coord_def target_pos, bool is_death)
{
// Apply pseudo-summon cap
int count_shroom = 0;
int count_lichen = 0;
for (monster_iterator mi; mi; ++mi)
{
if (mi->summoner == 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; n<num_total; n++)
{
const int choice = random_range(0, 2);
if (choice == 1 && num_shroom + count_shroom < 4)
num_shroom++;
else if (choice == 2 && num_lichen + count_lichen < 4)
num_lichen++;
}

int seen_shroom = 0;
int seen_lichen = 0;

if (num_shroom > 0)
{
for (int n=0; n<num_shroom; n++)
{
// XX: Maybe don't copy behaviour?
mgen_data mg(MONS_TOADSTOOL, BEH_COPY, target_pos,
_auto_autofoe(&agent), MG_AUTOFOE);
mg.set_summoned(&agent, 0, SPELL_NO_SPELL, GOD_NO_GOD); // Fedhas?

if (monster* spawn = create_monster(mg))
{
if (you.can_see(agent) || you.can_see(*spawn))
seen_shroom++;
}
}
}

if (num_lichen > 0)
{
for (int n=0; n<num_lichen; n++)
{
mgen_data mg(MONS_WOLF_LICHEN, BEH_COPY, target_pos,
_auto_autofoe(&agent), MG_AUTOFOE);
mg.set_summoned(&agent, 0, SPELL_NO_SPELL, GOD_NO_GOD); // Fedhas?

if (monster* spawn = create_monster(mg))
{
if (you.can_see(agent) || you.can_see(*spawn))
seen_lichen++;
}
}
}

if (!seen_shroom && !seen_lichen)
return false;

string seen_what = "";
if (seen_lichen)
seen_what += "lichen";
if (seen_lichen && seen_shroom)
seen_what += " and ";
if (seen_shroom)
seen_what += "toadstools";

mprf("%s sheds %s!", you.can_see(agent) ? agent.name(DESC_THE).c_str() : "Something",
seen_what.c_str());

return true;
}

bool summon_spider(const actor &agent, coord_def pos,
spell_type spell, int pow)
{
Expand Down
1 change: 1 addition & 0 deletions crawl-ref/source/spl-summoning.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ bool summon_hell_out_of_bat(const actor &agent, coord_def pos);
bool summon_spider(const actor &agent, coord_def pos, spell_type spell, int pow);
spret summon_spiders(actor &agent, int pow, bool fail = false);
bool summon_swarm_clone(const monster& agent, coord_def target_pos);
bool summon_detritus(const monster& agent, coord_def target_pos, bool is_death = false);

spret summon_butterflies();

Expand Down

0 comments on commit 976d416

Please sign in to comment.