diff options
author | Charles Otto <ottochar@gmail.com> | 2009-11-13 00:51:56 -0500 |
---|---|---|
committer | Charles Otto <ottochar@gmail.com> | 2009-11-13 00:51:56 -0500 |
commit | e7d888537c4d178a98e2ef1727a84d5132655d6c (patch) | |
tree | 79fc6a8cb3a521b7c4d6a9f8fb761a12c7d6ed23 | |
parent | 4a7b398e339f0b55ae3ce579a02c81c2c281216d (diff) | |
parent | 8075717d132ff61257a8836ce7854f71f1eb05f8 (diff) | |
download | crawl-ref-e7d888537c4d178a98e2ef1727a84d5132655d6c.tar.gz crawl-ref-e7d888537c4d178a98e2ef1727a84d5132655d6c.zip |
Merge spore experiments branch.
-rw-r--r-- | crawl-ref/source/beam.cc | 30 | ||||
-rw-r--r-- | crawl-ref/source/godabil.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/mon-abil.cc | 105 | ||||
-rw-r--r-- | crawl-ref/source/mon-abil.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/mon-act.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-info.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/mon-place.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/mon-stuff.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/monster.cc | 33 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 9 |
11 files changed, 181 insertions, 24 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index b5282066f7..973962a6af 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -2555,6 +2555,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; } @@ -3101,9 +3106,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 6af4394a09..69986ec4be 100644 --- a/crawl-ref/source/godabil.cc +++ b/crawl-ref/source/godabil.cc @@ -1133,9 +1133,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 43118781d1..9d53edc726 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -1388,4 +1388,109 @@ 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) + { + // The number field is used as a cooldown timer for this behavior. + if (monster->number <= 0) + { + 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, + attitude, + 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 = 40; + } + } + else + { + monster->number--; + } + + } +} + +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 527f71dc3e..810ccd43f4 100644 --- a/crawl-ref/source/mon-abil.h +++ b/crawl-ref/source/mon-abil.h @@ -16,4 +16,8 @@ void mon_nearby_ability(monsters *monster); 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/mon-act.cc b/crawl-ref/source/mon-act.cc index d9bce0dbfd..f699d7578e 100644 --- a/crawl-ref/source/mon-act.cc +++ b/crawl-ref/source/mon-act.cc @@ -3104,10 +3104,14 @@ static bool _do_move_monster(monsters *monster, const coord_def& delta) } mgrd(monster->pos()) = NON_MONSTER; + coord_def old_pos = monster->pos(); + monster->set_position(f); mgrd(monster->pos()) = monster_index(monster); + ballisto_on_move(monster, old_pos); + monster->check_redraw(monster->pos() - delta); monster->apply_location_effects(monster->pos() - delta); diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 38cf14ff50..dc677f3413 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/mon-info.cc b/crawl-ref/source/mon-info.cc index 659aa1cb7d..d32b8466d1 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/mon-place.cc b/crawl-ref/source/mon-place.cc index c326c359d8..dbf488e6a5 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -1163,12 +1163,6 @@ static int _place_monster_aux(const mgen_data &mg, mon->add_ench(ENCH_SLOWLY_DYING); } - if (mg.cls == MONS_BALLISTOMYCETE) - { - // This enchantment causes giant spore production. - mon->add_ench(ENCH_SPORE_PRODUCTION); - } - if (monster_can_submerge(mon, grd(fpos)) && !one_chance_in(5)) mon->add_ench(ENCH_SUBMERGED); diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc index 5cf5677528..0e8a3b436f 100644 --- a/crawl-ref/source/mon-stuff.cc +++ b/crawl-ref/source/mon-stuff.cc @@ -33,6 +33,7 @@ #include "kills.h" #include "message.h" #include "misc.h" +#include "mon-abil.h" #include "mon-behv.h" #include "mon-iter.h" #include "mon-place.h" @@ -1093,6 +1094,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"; @@ -1163,6 +1165,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); } @@ -1498,6 +1501,9 @@ int monster_die(monsters *monster, killer_type killer, you.remove_beholder(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) remove_auto_exclude(monster); diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 0c963631c7..869e65ce68 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -2158,6 +2158,11 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, result += cardinals[mon.number]; } + if (mon.type == MONS_BALLISTOMYCETE && desc != DESC_DBNAME) + { + result += mon.number ? "active " : ""; + } + // Done here to cover cases of undead versions of hydras. if (mons_species(nametype) == MONS_HYDRA && mon.number > 0 && desc != DESC_DBNAME) @@ -4986,22 +4991,23 @@ 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; + beh_type created_behavior = SAME_ATTITUDE(this); int rc = create_monster(mgen_data(MONS_GIANT_SPORE, created_behavior, @@ -5015,14 +5021,21 @@ void monsters::apply_enchantment(const mon_enchant &me) if (rc != -1) { env.mons[rc].behaviour = BEH_WANDER; + env.mons[rc].number = 20; if (observe_cell(adjacent) && observe_cell(pos())) mpr("A nearby fungus spawns a giant spore."); + + deactivate_ballistos(); } 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! @@ -6044,6 +6057,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->number ? 150 : 1500; + break; + case ENCH_ABJ: if (deg >= 6) cturn = 1000 / _mod_speed(10, mons->speed); diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 092ac802d3..648141b7a3 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -133,14 +133,13 @@ void monster_grid_updates() handle_monster_shouts(*mi); } + fedhas_neutralise(monster); if (!mi->visible_to(&you)) continue; - good_god_follower_attitude_change(*mi); - beogh_follower_convert(*mi); - slime_convert(*mi); - fedhas_neutralise(*mi); - + good_god_follower_attitude_change(monster); + beogh_follower_convert(monster); + slime_convert(monster); // XXX: Probably quite hackish. Allows for monsters going berserk when // they see the player. Currently only used for Duvessa, see the // function _elven_twin_dies in mon-stuff.cc. |