diff options
author | Stefan O'Rear <stefanor@cox.net> | 2009-10-24 22:12:10 -0700 |
---|---|---|
committer | Stefan O'Rear <stefanor@cox.net> | 2009-10-24 22:38:26 -0700 |
commit | e5c35dd08e149f985c77be908cfc3e9c69f2d13e (patch) | |
tree | 67adba7b180a1908c7d960e97861740af162f8d3 /crawl-ref/source/mutation.cc | |
parent | 5bae81aab842d440e045a1fa061a9553589d9616 (diff) | |
download | crawl-ref-e5c35dd08e149f985c77be908cfc3e9c69f2d13e.tar.gz crawl-ref-e5c35dd08e149f985c77be908cfc3e9c69f2d13e.zip |
Roll demonspawn mutations at the start of the game.
All demonspawn mutations are now stored in the player data, and are
determined at the same time. This makes a lot of things a lot simpler.
On the other hand, it means that the influence of skills and gods on
demonspawn mutations is now broken.
Diffstat (limited to 'crawl-ref/source/mutation.cc')
-rw-r--r-- | crawl-ref/source/mutation.cc | 174 |
1 files changed, 71 insertions, 103 deletions
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc index d1fa19613f..d792aab732 100644 --- a/crawl-ref/source/mutation.cc +++ b/crawl-ref/source/mutation.cc @@ -2644,17 +2644,13 @@ std::string mutation_name(mutation_type mut, int level, bool colour) return (result); } -// Use an attribute counter for how many demonic mutations a demonspawn has. -void demonspawn() +static mutation_type _demonspawn(FixedVector<int, NUM_MUTATIONS>& muts, int& powers, + int level) { mutation_type whichm = NUM_MUTATIONS; int counter = 0; - const int covered = _body_covered(); - - you.attribute[ATTR_NUM_DEMONIC_POWERS]++; - - mpr("Your demonic ancestry asserts itself...", MSGCH_INTRINSIC_GAIN); + powers++; // A demonspawn logically has six mutation slots, like [cold res, // negative res, teleport, black scales, mapping, repulsion field]. @@ -2674,14 +2670,14 @@ void demonspawn() { whichm = static_cast<mutation_type>(i); - if (! you.demon_pow[whichm]) + if (! muts[whichm]) { continue; } ++muts_seen; - if (you.demon_pow[whichm] < mutation_defs[whichm].levels) + if (muts[whichm] < mutation_defs[whichm].levels) { ++increasable_muts_seen; @@ -2719,28 +2715,9 @@ void demonspawn() { const mutation_def& mdef = mutation_defs[mut_to_increase]; - ASSERT(you.demon_pow[mut_to_increase] < mdef.levels); - - if (you.mutation[mut_to_increase] == mdef.levels) - { - // The player has our mutation as a temporary thing. Make - // it permanent. I want to put something like NetHack's "Your - // quickness feels more natural" here, but there doesn't seem - // to be a good way to do that. - mpr(mdef.gain[you.demon_pow[mut_to_increase]], MSGCH_MUTATION); - ++you.demon_pow[mut_to_increase]; - } - else - { - // None of the current demonspawn mutations is capable of - // failing. Be very careful if others are added; for instance, - // talons can fail to mutate if the player already has hooves. - // You'll need to add a case for clearing mutations in - // _handle_conflicting_mutations above. - ASSERT(perma_mutate(mut_to_increase, 1)); - } + ASSERT(muts[mut_to_increase] < mdef.levels); - return; + return mut_to_increase; } // Otherwise we're adding a brand new mutation @@ -2750,22 +2727,20 @@ void demonspawn() // if it's having trouble with the high level list. do { - if (you.experience_level >= 10) + if (level >= 10) { - if (you.skills[SK_CONJURATIONS] < 5) + if (1) { // good conjurers don't get bolt of draining whichm = MUT_SMITE; } - if (you.skills[SK_CONJURATIONS] < 10 && one_chance_in(4)) + if (one_chance_in(4)) { // good conjurers don't get hellfire whichm = MUT_HURL_HELLFIRE; } // Makhlebites have the summonings invocation - if ((you.religion != GOD_MAKHLEB || - you.piety < piety_breakpoint(3)) && - you.skills[SK_SUMMONINGS] < 5 && one_chance_in(3)) + if (one_chance_in(3)) { // good summoners don't get summon demon whichm = MUT_SUMMON_DEMONS; } @@ -2795,7 +2770,7 @@ void demonspawn() whichm = MUT_SHOCK_RESISTANCE; } - if (!you.mutation[MUT_CALL_TORMENT] && one_chance_in(15)) + if (!muts[MUT_CALL_TORMENT] && one_chance_in(15)) { whichm = MUT_TORMENT_RESISTANCE; } @@ -2805,89 +2780,56 @@ void demonspawn() whichm = MUT_NEGATIVE_ENERGY_RESISTANCE; } - if (!you.mutation[MUT_TORMENT_RESISTANCE] && one_chance_in(20)) + if (!muts[MUT_TORMENT_RESISTANCE] && one_chance_in(20)) { whichm = MUT_CALL_TORMENT; } - if (you.skills[SK_SUMMONINGS] < 5 && you.skills[SK_NECROMANCY] < 5 - && one_chance_in(12)) + if (one_chance_in(12)) { whichm = MUT_CONTROL_DEMONS; } - if (you.religion != GOD_MAKHLEB && one_chance_in(11)) + if (one_chance_in(11)) { whichm = MUT_DEATH_STRENGTH; } - // Theoretically, you could use this with Trog (for rods and - // some misc. items), but in general it's going to be much more - // useful for someone capable of casting spells. - if (you.religion != GOD_TROG - && you.religion != GOD_SIF_MUNA && one_chance_in(11)) + if (one_chance_in(11)) { whichm = MUT_CHANNEL_HELL; } - // Yredelemnulites have the raise dead invocation - if (you.religion != GOD_YREDELEMNUL - && you.skills[SK_SUMMONINGS] < 3 - && you.skills[SK_NECROMANCY] < 3 && one_chance_in(10)) + if (one_chance_in(10)) { whichm = MUT_RAISE_DEAD; } - if (you.skills[SK_UNARMED_COMBAT] > 5) + if (one_chance_in(25)) { - // Drain Life only works if you're unarmed, so only - // give it if unarmed is your best attacking skill. - skill_type wpn_skill = best_skill(SK_SHORT_BLADES, SK_STAVES); - if ((you.skills[SK_UNARMED_COMBAT] > you.skills[wpn_skill]) - && one_chance_in(14)) - { - whichm = MUT_DRAIN_LIFE; - } + whichm = MUT_DRAIN_LIFE; } } // check here so we can see if we need to extend our options - if (whichm != NUM_MUTATIONS && you.mutation[whichm] != 0) + if (whichm != NUM_MUTATIONS && muts[whichm] != 0) whichm = NUM_MUTATIONS; - if (you.experience_level < 10 + if (level < 10 || (counter > 0 && whichm == NUM_MUTATIONS)) { - if ((!you.mutation[MUT_THROW_FROST] // only one of these - && !you.mutation[MUT_THROW_FLAMES] - && !you.mutation[MUT_BREATHE_FLAMES]) - && (!you.skills[SK_CONJURATIONS] // conjurers seldomly - || one_chance_in(5)) - // Makhlebites seldom - && (you.religion != GOD_MAKHLEB || one_chance_in(4)) - && (!you.skills[SK_ICE_MAGIC] // already ice & fire? - || !you.skills[SK_FIRE_MAGIC])) + if (!muts[MUT_THROW_FROST] // only one of these + && !muts[MUT_THROW_FLAMES] + && !muts[MUT_BREATHE_FLAMES]) { - // try to give the flavour the character doesn't have - - // neither - if (!you.skills[SK_FIRE_MAGIC] && !you.skills[SK_ICE_MAGIC]) - whichm = (coinflip() ? MUT_THROW_FLAMES : MUT_THROW_FROST); - else if (!you.skills[SK_FIRE_MAGIC]) - whichm = MUT_THROW_FLAMES; - else if (!you.skills[SK_ICE_MAGIC]) - whichm = MUT_THROW_FROST; - // both - else - whichm = (coinflip() ? MUT_THROW_FLAMES : MUT_THROW_FROST); + whichm = (coinflip() ? MUT_THROW_FLAMES : MUT_THROW_FROST); } // summoners and Makhlebites don't get summon imp - if (!you.skills[SK_SUMMONINGS] && you.religion != GOD_MAKHLEB - && one_chance_in(3)) + if (one_chance_in(3)) { - whichm = (you.experience_level < 10) ? MUT_SUMMON_MINOR_DEMONS - : MUT_SUMMON_DEMONS; + whichm = (level < 10) ? MUT_SUMMON_MINOR_DEMONS + : MUT_SUMMON_DEMONS; } if (one_chance_in(4)) @@ -2910,7 +2852,7 @@ void demonspawn() whichm = MUT_ACUTE_VISION; } - if (!you.skills[SK_POISON_MAGIC] && one_chance_in(7)) + if (one_chance_in(7)) { whichm = MUT_SPIT_POISON; } @@ -2925,22 +2867,21 @@ void demonspawn() whichm = MUT_TELEPORT_CONTROL; } - if (!you.mutation[MUT_THROW_FROST] // not with these - && !you.mutation[MUT_THROW_FLAMES] - && !you.mutation[MUT_BREATHE_FLAMES] - && !you.skills[SK_FIRE_MAGIC] // or with fire already + if (!muts[MUT_THROW_FROST] // not with these + && !muts[MUT_THROW_FLAMES] + && !muts[MUT_BREATHE_FLAMES] && one_chance_in(5)) { whichm = MUT_BREATHE_FLAMES; } - if (!you.skills[SK_TRANSLOCATIONS] && one_chance_in(12)) + if (one_chance_in(12)) { - whichm = (you.experience_level < 10) ? MUT_BLINK - : MUT_TELEPORT_AT_WILL; + whichm = (level < 10) ? MUT_BLINK + : MUT_TELEPORT_AT_WILL; } - if (covered < 3 && one_chance_in( 1 + covered * 5 )) + if (1) { if (one_chance_in(10)) { @@ -2979,26 +2920,53 @@ void demonspawn() whichm = MUT_REPULSION_FIELD; } - if (one_chance_in( (you.experience_level < 10) ? 5 : 20 )) + if (one_chance_in( (level < 10) ? 5 : 20 )) { whichm = MUT_HORNS; } } - if (whichm != NUM_MUTATIONS && you.mutation[whichm] != 0) + if (whichm != NUM_MUTATIONS && muts[whichm] != 0) whichm = NUM_MUTATIONS; counter++; } while (whichm == NUM_MUTATIONS && counter < 5000); - if (whichm == NUM_MUTATIONS || !perma_mutate( whichm, 1 )) + if (whichm == NUM_MUTATIONS) { - // Unlikely but remotely possible; I know this is a cop-out. - modify_stat(STAT_STRENGTH, 1, true, "demonspawn mutation"); - modify_stat(STAT_INTELLIGENCE, 1, true, "demonspawn mutation"); - modify_stat(STAT_DEXTERITY, 1, true, "demonspawn mutation"); - mpr("You feel much better now.", MSGCH_INTRINSIC_GAIN); + return MUT_STRONG; + } + + return whichm; +} + +void roll_demonspawn_mutations() +{ + FixedVector<int, NUM_MUTATIONS> muts; + int npowers = 0; + + muts.init(0); + you.demon_trait.init(NUM_MUTATIONS); + + for (int level = 2; level <= 27; ++level) + { + // We want 17 (6*3 - 1) random attemps to raise or add a + // mutation in the 26 level ups. The following check is + // equivalent to taking a string of 17 1s and 9 0s and + // shuffling it. + + if (x_chance_in_y(17 - npowers, 28 - level)) + { + mutation_type newmut = _demonspawn(muts, npowers, level); + +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Demonspawn will gain %s at level %d", + get_mutation_def(newmut).wizname, level); +#endif + you.demon_trait[level-2] = newmut; + muts[newmut]++; + } } } |