From 37ba8b3ae6c9c7f6b39e372c4dd8f305f69923be Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Wed, 11 Nov 2009 22:31:41 -0500 Subject: Give giant spores a chance of spawning ballistos while wandering Give giant spores a chance of creating a ballistomycete when they move while wandering. This ability is on a timer, so they can't create more than 1 ballisto per 20 turns. Numbers may need tweaking. --- crawl-ref/source/mon-abil.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'crawl-ref/source/mon-abil.cc') diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc index 73d0547f6c..3c93b540a2 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -1435,4 +1435,39 @@ void mon_nearby_ability(monsters *monster) } } +// When giant spores move (while wandering) maybe place a spore on the +// square they move off of. +void ballisto_on_move(monsters * monster, const coord_def & position) +{ + if (monster->type == MONS_GIANT_SPORE + && monster->behaviour == BEH_WANDER) + { + // The number field is used as a cooldown timer for this behavior. + if (monster->number <= 0) + { + if (one_chance_in(4)) + { + int rc = create_monster(mgen_data(MONS_BALLISTOMYCETE, + SAME_ATTITUDE(monster), + 0, + 0, + position, + MHITNOT, + MG_FORCE_PLACE)); + + if (rc != -1 && you.can_see(&env.mons[rc])) + { + mprf("A ballistomycete grows in the wake of the spore."); + } + monster->number = 20; + } + } + else + { + monster->number--; + } + + } +} + -- cgit v1.2.3-54-g00ecf From 4cf89bf43fe0847385567b94f0a61a16003561fb Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Wed, 11 Nov 2009 23:32:33 -0500 Subject: Change the ballistomycete activation mechanic Give ballistomycetes a counter, when it's at zero they have the slow spawn rate (are considered inactive), when it's greater than zero they have the fast spawn rate. Killing a ballisto gives +1 to any others on the level, a ballisto spawning a spore subtracts 1 from its own counter --- crawl-ref/source/mon-abil.cc | 3 +-- crawl-ref/source/mon-info.cc | 3 +++ crawl-ref/source/monster.cc | 17 +++++++++++++++-- crawl-ref/source/monstuff.cc | 6 ++++-- 4 files changed, 23 insertions(+), 6 deletions(-) (limited to 'crawl-ref/source/mon-abil.cc') diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc index 3c93b540a2..5ed1f0435b 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -1439,8 +1439,7 @@ void mon_nearby_ability(monsters *monster) // square they move off of. void ballisto_on_move(monsters * monster, const coord_def & position) { - if (monster->type == MONS_GIANT_SPORE - && monster->behaviour == BEH_WANDER) + if (monster->type == MONS_GIANT_SPORE) { // The number field is used as a cooldown timer for this behavior. if (monster->number <= 0) diff --git a/crawl-ref/source/mon-info.cc b/crawl-ref/source/mon-info.cc index 55d47f1387..12f64499dc 100644 --- a/crawl-ref/source/mon-info.cc +++ b/crawl-ref/source/mon-info.cc @@ -115,6 +115,9 @@ bool monster_info::less_than(const monster_info& m1, if (m1type == MONS_SLIME_CREATURE) return (m1.m_mon->number > m2.m_mon->number); + if (m1type == MONS_BALLISTOMYCETE) + return ((m1.m_mon->number > 0) > (m2.m_mon->number > 0)); + if (zombified) { // Because of the type checks above, if one of the two is zombified, so diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 77c9753884..b3fda3a9d7 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -2156,7 +2156,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, if (mon.type == MONS_BALLISTOMYCETE && desc != DESC_DBNAME) { - result += mon.colour == LIGHTRED ? "Active " : ""; + result += mon.number ? "active " : ""; } // Done here to cover cases of undead versions of hydras. @@ -5014,6 +5014,19 @@ void monsters::apply_enchantment(const mon_enchant &me) if (observe_cell(adjacent) && observe_cell(pos())) mpr("A nearby fungus spawns a giant spore."); + + // Decrease the count and maybe become inactive + // again + if(this->number) + { + this->number--; + if(this->number == 0) + { + this->colour = MAGENTA; + if(you.can_see(this)) + mprf("A nearby ballistomycete calms down."); + } + } } break; } @@ -6044,7 +6057,7 @@ int mon_enchant::calc_duration(const monsters *mons, case ENCH_SPORE_PRODUCTION: // The duration of the spore production timer depends on the color // of the fungus - cturn = mons->colour == LIGHTRED ? 150 : 1500; + cturn = mons->number ? 150 : 1500; break; case ENCH_ABJ: diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 1334751541..ae91249f6b 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1445,13 +1445,15 @@ static void _activate_ballistomycetes( monsters * monster) && env.mons[i].alive() && env.mons[i].type == MONS_BALLISTOMYCETE) { - if(env.mons[i].colour != LIGHTRED) + env.mons[i].number++; + // 0 -> 1 means the ballisto moves onto the faster spawn + // timer and changes color + if(env.mons[i].number == 1) { 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++; -- cgit v1.2.3-54-g00ecf From 8075717d132ff61257a8836ce7854f71f1eb05f8 Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Thu, 12 Nov 2009 20:30:12 -0500 Subject: Change ballistomycete spore mechanics again New status: if a ballistomycete or giant spore dies any ballistos on the level get +1 to a counter. Ballistos with a count higher than zero get spore production on a short (~150 turn) timer. When a spore is spawned (by a ballisto) the count of all ballistos on the level is decreased by 1. --- crawl-ref/source/beam.cc | 30 +++++++++++++++-- crawl-ref/source/godabil.cc | 3 -- crawl-ref/source/mon-abil.cc | 79 +++++++++++++++++++++++++++++++++++++++++--- crawl-ref/source/mon-abil.h | 2 ++ crawl-ref/source/monplace.cc | 6 ---- crawl-ref/source/monster.cc | 15 ++------- crawl-ref/source/monstuff.cc | 45 +++---------------------- 7 files changed, 112 insertions(+), 68 deletions(-) (limited to 'crawl-ref/source/mon-abil.cc') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 8a10cc4531..27600e0a31 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -2538,6 +2538,11 @@ int mons_adjust_flavoured(monsters *monster, bolt &pbolt, int hurted, } break; + case BEAM_SPORE: + if (monster->type == MONS_BALLISTOMYCETE) + hurted = 0; + break; + default: break; } @@ -3092,9 +3097,30 @@ void bolt::affect_ground() && mons_class_can_pass(MONS_BALLISTOMYCETE, env.grid(pos())) && !actor_at(pos())) { + beh_type beh; // Half the fungi in arena mode are friendly. - beh_type beh = (crawl_state.arena && coinflip()) ? BEH_FRIENDLY - : BEH_HOSTILE; + if(crawl_state.arena) + { + beh = coinflip() ? BEH_FRIENDLY : BEH_HOSTILE; + } + else + { + switch(this->attitude) + { + case ATT_NEUTRAL: + beh = BEH_NEUTRAL; + break; + + case ATT_FRIENDLY: + case ATT_GOOD_NEUTRAL: + beh = BEH_GOOD_NEUTRAL; + break; + + default: + beh = BEH_HOSTILE; + break; + } + } int rc = create_monster(mgen_data(MONS_BALLISTOMYCETE, beh, diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc index a7f4c77484..8bac2d4ee0 100644 --- a/crawl-ref/source/godabil.cc +++ b/crawl-ref/source/godabil.cc @@ -1128,9 +1128,6 @@ bool evolve_flora() current_plant->del_ench(ENCH_SLOWLY_DYING); current_plant->del_ench(ENCH_SPORE_PRODUCTION); - if (current_plant->mons_species() == MONS_BALLISTOMYCETE) - current_plant->add_ench(ENCH_SPORE_PRODUCTION); - // Maybe we can upgrade it again? if (_possible_evolution(current_plant, temp_conversion) && temp_conversion.cost <= points) diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc index 5ed1f0435b..16bde8d4f4 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -1446,8 +1446,13 @@ void ballisto_on_move(monsters * monster, const coord_def & position) { if (one_chance_in(4)) { + beh_type attitude = SAME_ATTITUDE(monster); + if(!crawl_state.arena && attitude == BEH_FRIENDLY) + { + attitude = BEH_GOOD_NEUTRAL; + } int rc = create_monster(mgen_data(MONS_BALLISTOMYCETE, - SAME_ATTITUDE(monster), + attitude, 0, 0, position, @@ -1455,10 +1460,9 @@ void ballisto_on_move(monsters * monster, const coord_def & position) MG_FORCE_PLACE)); if (rc != -1 && you.can_see(&env.mons[rc])) - { mprf("A ballistomycete grows in the wake of the spore."); - } - monster->number = 20; + + monster->number = 40; } } else @@ -1469,4 +1473,71 @@ void ballisto_on_move(monsters * monster, const coord_def & position) } } +void activate_ballistomycetes( monsters * monster) +{ + if(!monster || monster->type != MONS_BALLISTOMYCETE && monster->type != MONS_GIANT_SPORE) + 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) + { + env.mons[i].number++; + // 0 -> 1 means the ballisto moves onto the faster spawn + // timer and changes color + if(env.mons[i].number == 1) + { + 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..."); +} + +void deactivate_ballistos() +{ + for(unsigned i=0;i < env.mons.size(); i++) + { + if(env.mons[i].alive() + && env.mons[i].type == MONS_BALLISTOMYCETE) + { + monsters * temp = &env.mons[i]; + // Decrease the count and maybe become inactive + // again + if(temp->number) + { + temp->number--; + if(temp->number == 0) + { + temp->colour = MAGENTA; + temp->del_ench(ENCH_SPORE_PRODUCTION); + //temp->add_ench(ENCH_SPORE_PRODUCTION); + if(you.can_see(temp)) + mprf("A nearby ballistomycete calms down."); + } + } + + + } + } +} + diff --git a/crawl-ref/source/mon-abil.h b/crawl-ref/source/mon-abil.h index 7addf706ec..810ccd43f4 100644 --- a/crawl-ref/source/mon-abil.h +++ b/crawl-ref/source/mon-abil.h @@ -17,5 +17,7 @@ bool ugly_thing_mutate(monsters *ugly, bool proximity = false); bool slime_split_merge(monsters *thing); void ballisto_on_move(monsters * monster, const coord_def & pos); +void activate_ballistomycetes( monsters * monster); +void deactivate_ballistos(); #endif diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 8d1edb789e..b0282aeaf1 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -1159,12 +1159,6 @@ static int _place_monster_aux(const mgen_data &mg, mons.add_ench(ENCH_SLOWLY_DYING); } - if (mg.cls == MONS_BALLISTOMYCETE) - { - // This enchantment causes giant spore production. - mons.add_ench(ENCH_SPORE_PRODUCTION); - } - if (monster_can_submerge(&mons, grd(fpos)) && !one_chance_in(5)) mons.add_ench(ENCH_SUBMERGED); diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index b3fda3a9d7..4b706d8a47 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -5010,23 +5010,12 @@ void monsters::apply_enchantment(const mon_enchant &me) if (rc != -1) { env.mons[rc].behaviour = BEH_WANDER; - env.mons[rc].number = 10; + env.mons[rc].number = 20; if (observe_cell(adjacent) && observe_cell(pos())) mpr("A nearby fungus spawns a giant spore."); - // Decrease the count and maybe become inactive - // again - if(this->number) - { - this->number--; - if(this->number == 0) - { - this->colour = MAGENTA; - if(you.can_see(this)) - mprf("A nearby ballistomycete calms down."); - } - } + deactivate_ballistos(); } break; } diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index ae91249f6b..d94598974c 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -33,6 +33,7 @@ #include "kills.h" #include "message.h" #include "misc.h" +#include "mon-abil.h" #include "mon-behv.h" #include "monplace.h" #include "monspeak.h" @@ -1087,6 +1088,7 @@ static bool _spore_goes_pop(monsters *monster, killer_type killer, beam.thrower = crawl_state.arena ? KILL_MON : monster->attitude == ATT_FRIENDLY ? KILL_YOU : KILL_MON; beam.aux_source.clear(); + beam.attitude = monster->attitude; if (YOU_KILL(killer)) beam.aux_source = "set off by themselves"; @@ -1157,6 +1159,7 @@ static bool _spore_goes_pop(monsters *monster, killer_type killer, // FIXME: show_more == mons_near(monster) beam.explode(); + activate_ballistomycetes(monster); // Monster died in explosion, so don't re-attach it to the grid. return (true); } @@ -1432,45 +1435,6 @@ 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) - { - env.mons[i].number++; - // 0 -> 1 means the ballisto moves onto the faster spawn - // timer and changes color - if(env.mons[i].number == 1) - { - 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) @@ -1494,7 +1458,8 @@ int monster_die(monsters *monster, killer_type killer, you.remove_beholder(monster); - _activate_ballistomycetes(monster); + if(monster->type == MONS_BALLISTOMYCETE) + activate_ballistomycetes(monster); // Clear auto exclusion now the monster is killed -- if we know about it. if (mons_near(monster) || wizard) -- cgit v1.2.3-54-g00ecf