diff options
author | Charles Otto <ottochar@gmail.com> | 2009-11-11 00:47:15 -0500 |
---|---|---|
committer | Charles Otto <ottochar@gmail.com> | 2009-11-11 00:47:58 -0500 |
commit | 21cc906692321fd60c3fa6ab4780ce1fa0f083c6 (patch) | |
tree | 0936f66d5b2420dbc242d8b0d3afe153b62dc63c /crawl-ref/source | |
parent | 4bf7a0a7ff66c0eb13674d4467dcee5c1301a359 (diff) | |
download | crawl-ref-21cc906692321fd60c3fa6ab4780ce1fa0f083c6.tar.gz crawl-ref-21cc906692321fd60c3fa6ab4780ce1fa0f083c6.zip |
Change ballistomycete spore spawning mechanics
Make spore production use a timer instead of a chance per turn.
Give ballistomycetes 2 basic states, for now differentiated by glyph
color. They start out magenta and have a slow spawn rate (1 per ~1500
turns), when a ballisto dies any others on the level become active,
changing color to light red and spawning spores quickly (1 per ~150
turns)
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/mon-data.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/monster.cc | 36 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 39 |
3 files changed, 65 insertions, 12 deletions
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index bf09742926..1360ed5987 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -713,7 +713,7 @@ static monsterentry mondata[] = { }, { - MONS_BALLISTOMYCETE, 'f', LIGHTRED, "ballistomycete", + MONS_BALLISTOMYCETE, 'f', MAGENTA, "ballistomycete", M_STATIONARY, MR_RES_POISON, 0, 10, MONS_FUNGUS, MONS_FUNGUS, MH_PLANT, MAG_IMMUNE, diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index ab8dc0dba3..1c46b41f98 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -4976,42 +4976,50 @@ void monsters::apply_enchantment(const mon_enchant &me) break; case ENCH_SPORE_PRODUCTION: - // Very low chance of actually making a spore on each turn. - if(one_chance_in(5000)) + + // Reduce the timer, if that means we lose the enchantment then + // spawn a spore and re-add the enchantment + if(decay_enchantment(me)) { + // Search for an open adjacent square to place a spore on int idx[] = {0, 1, 2, 3, 4, 5, 6, 7}; std::random_shuffle(idx, idx + 8); for (unsigned i = 0; i < 8; ++i) { coord_def adjacent = this->pos() + Compass[idx[i]]; + if (mons_class_can_pass(MONS_GIANT_SPORE, env.grid(adjacent)) - && !actor_at(adjacent)) + && !actor_at(adjacent)) { beh_type created_behavior = BEH_HOSTILE; if (this->attitude == ATT_FRIENDLY) - created_behavior = BEH_FRIENDLY; + created_behavior = BEH_FRIENDLY; int rc = create_monster(mgen_data(MONS_GIANT_SPORE, - created_behavior, - 0, - 0, - adjacent, - MHITNOT, - MG_FORCE_PLACE)); + created_behavior, + 0, + 0, + adjacent, + MHITNOT, + MG_FORCE_PLACE)); if (rc != -1) { env.mons[rc].behaviour = BEH_WANDER; if (observe_cell(adjacent) && observe_cell(pos())) - mpr("A nearby fungus spawns a giant spore."); + mpr("A nearby fungus spawns a giant spore."); } break; } } + // Re=add the enchantment (this resets the spore production + // timer). + this->add_ench(ENCH_SPORE_PRODUCTION); } + break; case ENCH_GLOWING_SHAPESHIFTER: // This ench never runs out! @@ -6030,6 +6038,12 @@ int mon_enchant::calc_duration(const monsters *mons, // of this function is excessive for toadstools. -cao return (2 * FRESHEST_CORPSE + random2(10)) * speed_to_duration(mons->speed) * mons->speed / 10; + case ENCH_SPORE_PRODUCTION: + // The duration of the spore production timer depends on the color + // of the fungus + cturn = mons->colour == LIGHTRED ? 150 : 1500; + break; + case ENCH_ABJ: if (deg >= 6) cturn = 1000 / _mod_speed(10, mons->speed); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 201d374041..1334751541 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1432,6 +1432,43 @@ static int _destroy_tentacles(monsters *head) return tent; } +static void _activate_ballistomycetes( monsters * monster) +{ + if(!monster || monster->type != MONS_BALLISTOMYCETE) + return; + + bool activated_others = false; + int seen_others = 0; + for(int i=0; i < int(env.mons.size()); ++i) + { + if(i != monster->mindex() + && env.mons[i].alive() + && env.mons[i].type == MONS_BALLISTOMYCETE) + { + if(env.mons[i].colour != LIGHTRED) + { + env.mons[i].colour = LIGHTRED; + // Reset the spore production timer. + env.mons[i].del_ench(ENCH_SPORE_PRODUCTION, false); + env.mons[i].add_ench(ENCH_SPORE_PRODUCTION); + + activated_others = true; + if(you.can_see(&env.mons[i])) + seen_others++; + } + } + } + + // How to do messaging? Message on kill no matter what, only if you see + // other ballistos get angry, only if other ballistos get angry + // (seen or not). Also need a message if a ballisto suddenly becomes + // angry + if(mons_near(monster) && activated_others) + mprf("You feel ballistomycets on the level are angry now?"); + else if (seen_others > 0) + mprf("The ballistomycete appears angry..."); +} + // Returns the slot of a possibly generated corpse or -1. int monster_die(monsters *monster, killer_type killer, int killer_index, bool silent, bool wizard) @@ -1455,6 +1492,8 @@ int monster_die(monsters *monster, killer_type killer, you.remove_beholder(monster); + _activate_ballistomycetes(monster); + // Clear auto exclusion now the monster is killed -- if we know about it. if (mons_near(monster) || wizard) remove_auto_exclude(monster); |