From f903462645b80653998fe987732752038be862d4 Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Sun, 17 Jan 2010 17:36:51 -0500 Subject: Allow toadstools on tiles Fedhas worshipers are standing on Mostly this is so that decomposition can work on corpses the player is standing on. Update the decomposition ability description accordingly. --- crawl-ref/source/dat/descript/ability.txt | 2 +- crawl-ref/source/effects.cc | 17 ++++++--- crawl-ref/source/godabil.cc | 59 ++++++++++++++++--------------- crawl-ref/source/godabil.h | 1 + crawl-ref/source/mon-place.cc | 11 ++++-- 5 files changed, 52 insertions(+), 38 deletions(-) diff --git a/crawl-ref/source/dat/descript/ability.txt b/crawl-ref/source/dat/descript/ability.txt index 083724a29d..ac9fb76c8b 100644 --- a/crawl-ref/source/dat/descript/ability.txt +++ b/crawl-ref/source/dat/descript/ability.txt @@ -361,7 +361,7 @@ Recall your orcish followers from anywhere on the level to your immediate surrou # Fedhas Decomposition -Cause corpses in your field of vision to rapidly decay. Corpses with a monster (or you) on top of them will not be affected. +Cause corpses in your field of vision to rapidly decay. Corpses with a monster on top of them will not be affected. %%%% Sunlight diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index ee09fc5689..0e58c61316 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -4643,16 +4643,18 @@ int spawn_corpse_mushrooms(item_def &corpse, fringe.pop(); - actor * occupant = NULL; + monsters * monster = monster_at(current); + + bool player_occupant = you.pos() == current; // Is this square occupied by a non mushroom? - if ((occupant = actor_at(current)) - && occupant->mons_species() != MONS_TOADSTOOL) + if (monster && monster->mons_species() != MONS_TOADSTOOL + || player_occupant && you.religion != GOD_FEDHAS) { continue; } - if (!occupant) + if (!monster) { const int mushroom = create_monster( mgen_data(MONS_TOADSTOOL, @@ -4693,7 +4695,12 @@ int spawn_corpse_mushrooms(item_def &corpse, } placed_targets++; - if (you.see_cell(current)) + if (current == you.pos()) + { + mprf("A toadstool grows at your feet."); + current= env.mons[mushroom].pos(); + } + else if (you.see_cell(current)) seen_targets++; } else diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc index 2c42e8f9e6..fc4e9712dc 100644 --- a/crawl-ref/source/godabil.cc +++ b/crawl-ref/source/godabil.cc @@ -315,13 +315,19 @@ void yred_make_enslaved_soul(monsters *mon, bool force_hostile, } } +bool fedhas_passthrough_class(const monster_type mc) +{ + return (you.religion == GOD_FEDHAS + && mons_class_is_plant(mc) + && mons_class_is_stationary(mc)); +} + // Fedhas allows worshipers to walk on top of stationary plants and // fungi. bool fedhas_passthrough(const monsters * target) { - return (target && you.religion == GOD_FEDHAS - && mons_is_plant(target) - && mons_is_stationary(target) + return (target + && fedhas_passthrough_class(target->type) && (target->type != MONS_OKLOB_PLANT || target->attitude != ATT_HOSTILE)); } @@ -371,47 +377,42 @@ int fungal_bloom() for (radius_iterator i(you.pos(), LOS_RADIUS); i; ++i) { - actor *target = actor_at(*i); - if (target && (target->atype() == ACT_PLAYER - || target->is_summoned())) - { + monsters * target = monster_at(*i); + if (target && target->is_summoned()) continue; - } - - monsters * mons = monster_at(*i); - if (mons && mons->mons_species() != MONS_TOADSTOOL) + if (target && target->mons_species() != MONS_TOADSTOOL) { - switch (mons_genus(mons->mons_species())) + switch (mons_genus(target->mons_species())) { case MONS_ZOMBIE_SMALL: // Maybe turn a zombie into a skeleton. - if (mons_skeleton(mons_zombie_base(mons))) + if (mons_skeleton(mons_zombie_base(target))) { processed_count++; monster_type skele_type = MONS_SKELETON_LARGE; - if (mons_zombie_size(mons_zombie_base(mons)) == Z_SMALL) + if (mons_zombie_size(mons_zombie_base(target)) == Z_SMALL) skele_type = MONS_SKELETON_SMALL; // Killing and replacing the zombie since upgrade_type // doesn't get skeleton speed right (and doesn't // reduce the victim's HP). This is awkward. -cao - mgen_data mg(skele_type, mons->behaviour, NULL, 0, 0, - mons->pos(), - mons->foe, + mgen_data mg(skele_type, target->behaviour, NULL, 0, 0, + target->pos(), + target->foe, MG_FORCE_BEH | MG_FORCE_PLACE, - mons->god, - mons_zombie_base(mons), - mons->number); + target->god, + mons_zombie_base(target), + target->number); - unsigned monster_flags = mons->flags; - int current_hp = mons->hit_points; - mon_enchant_list ench = mons->enchantments; + unsigned monster_flags = target->flags; + int current_hp = target->hit_points; + mon_enchant_list ench = target->enchantments; - simple_monster_message(mons, "'s flesh rots away."); + simple_monster_message(target, "'s flesh rots away."); - monster_die(mons, KILL_MISC, NON_MONSTER, true); + monster_die(target, KILL_MISC, NON_MONSTER, true); int monster = create_monster(mg); env.mons[monster].flags = monster_flags; env.mons[monster].enchantments = ench; @@ -427,11 +428,11 @@ int fungal_bloom() // Ghoul-type monsters are always destroyed. case MONS_GHOUL: { - simple_monster_message(mons, " rots away and dies."); + simple_monster_message(target, " rots away and dies."); - coord_def pos = mons->pos(); - int colour = mons->colour; - int corpse = monster_die(mons, KILL_MISC, NON_MONSTER, true); + coord_def pos = target->pos(); + int colour = target->colour; + int corpse = monster_die(target, KILL_MISC, NON_MONSTER, true); kills = true; // If a corpse didn't drop, create a toadstool. diff --git a/crawl-ref/source/godabil.h b/crawl-ref/source/godabil.h index ed787249bf..a177e9071c 100644 --- a/crawl-ref/source/godabil.h +++ b/crawl-ref/source/godabil.h @@ -20,6 +20,7 @@ bool jiyva_remove_bad_mutation(); bool beogh_water_walk(); void yred_make_enslaved_soul(monsters *mon, bool force_hostile = false, bool quiet = false, bool unrestricted = false); +bool fedhas_passthrough_class(const monster_type mc); bool fedhas_passthrough(const monsters * target); bool fedhas_shoot_through(const bolt & beam, const monsters * victim); int fungal_bloom(); diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc index 2c329e544a..dd949281c6 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -18,6 +18,7 @@ #include "directn.h" #include "dungeon.h" #include "fprop.h" +#include "godabil.h" #include "externs.h" #include "options.h" #include "ghost.h" @@ -715,7 +716,9 @@ static int _is_near_stairs(coord_def &p) static bool _valid_monster_generation_location( const mgen_data &mg, const coord_def &mg_pos) { - if (!in_bounds(mg_pos) || actor_at(mg_pos)) + if (!in_bounds(mg_pos) + || monster_at(mg_pos) + || you.pos() == mg_pos && !fedhas_passthrough_class(mg.cls)) return (false); const monster_type montype = (mons_class_is_zombified(mg.cls) ? mg.base_type @@ -1097,7 +1100,8 @@ static int _place_monster_aux(const mgen_data &mg, // If the space is occupied, try some neighbouring square instead. if (first_band_member && in_bounds(mg.pos) && (mg.behaviour == BEH_FRIENDLY || !is_sanctuary(mg.pos)) - && actor_at(mg.pos) == NULL + && !monster_at(mg.pos) + && (you.pos() != mg.pos || fedhas_passthrough_class(mg.cls)) && (force_pos || monster_habitable_grid(montype, grd(mg.pos)))) { fpos = mg.pos; @@ -2878,7 +2882,8 @@ int create_monster(mgen_data mg, bool fail_msg) if (!mg.force_place() || !in_bounds(mg.pos) - || actor_at(mg.pos) + || monster_at(mg.pos) + || you.pos() == mg.pos && !fedhas_passthrough_class(mg.cls) || !mons_class_can_pass(montype, grd(mg.pos))) { mg.pos = find_newmons_square(montype, mg.pos); -- cgit v1.2.3