summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mutation.cc
diff options
context:
space:
mode:
authorNicholas Feinberg <pleasingfung@gmail.com>2014-06-09 22:40:35 -0700
committerNicholas Feinberg <pleasingfung@gmail.com>2014-06-09 22:40:45 -0700
commit07b0eb35980d0d7ee4d0438a7e8ae665146e3e70 (patch)
tree1235e7b52fd53b74f572a9c9a50ce8aee7e897e8 /crawl-ref/source/mutation.cc
parent7e13d23ab01eeb5149a44123619e466b4099d8f8 (diff)
downloadcrawl-ref-07b0eb35980d0d7ee4d0438a7e8ae665146e3e70.tar.gz
crawl-ref-07b0eb35980d0d7ee4d0438a7e8ae665146e3e70.zip
Refactor mutations
Diffstat (limited to 'crawl-ref/source/mutation.cc')
-rw-r--r--crawl-ref/source/mutation.cc168
1 files changed, 83 insertions, 85 deletions
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index a0cb198185..afc387a23a 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -84,21 +84,38 @@ equipment_type beastly_slot(int mut)
}
}
-enum mut_total
+static bool _mut_has_use(const mutation_def &mut, mut_use_type use)
{
- MT_GOOD,
- MT_BAD,
- NUM_MT
-};
+ return mut.uses & MFLAG(use);
+}
+
+#define MUT_BAD(mut) _mut_has_use((mut), MU_USE_BAD)
+#define MUT_GOOD(mut) _mut_has_use((mut), MU_USE_GOOD)
+
+static int _mut_weight(const mutation_def &mut, mut_use_type use)
+{
+ switch (use)
+ {
+ case MU_USE_JIYVA:
+ case MU_USE_QAZLAL:
+ case MU_USE_XOM:
+ case MU_USE_CORRUPT:
+ return 1;
+ case MU_USE_GOOD:
+ case MU_USE_BAD:
+ default:
+ return mut.weight;
+ }
+}
static int mut_index[NUM_MUTATIONS];
-static int total_rarity[NUM_MT];
+static int total_weight[NUM_MU_USE];
void init_mut_index()
{
for (int i = 0; i < NUM_MUTATIONS; ++i)
mut_index[i] = -1;
- memset(total_rarity, 0, sizeof(total_rarity));
+ memset(total_weight, 0, sizeof(total_weight));
for (unsigned int i = 0; i < ARRAYSZ(mut_data); ++i)
{
@@ -106,7 +123,9 @@ void init_mut_index()
ASSERT_RANGE(mut, 0, NUM_MUTATIONS);
ASSERT(mut_index[mut] == -1);
mut_index[mut] = i;
- total_rarity[mut_data[i].bad ? MT_BAD : MT_GOOD] += mut_data[i].rarity;
+ for (int mt = MU_USE_MIN; mt < NUM_MU_USE; mt++)
+ if (_mut_has_use(mut_data[i], (mut_use_type)mt))
+ total_weight[mt] += _mut_weight(mut_data[i], (mut_use_type)mt);
}
}
@@ -931,17 +950,18 @@ void display_mutations()
static int _calc_mutation_amusement_value(mutation_type which_mutation)
{
- int amusement = 12 * (11 - get_mutation_def(which_mutation).rarity);
+ int amusement = 12 * (11 - get_mutation_def(which_mutation).weight);
- if (mut_data[which_mutation].bad == MT_GOOD)
+ if (MUT_GOOD(mut_data[which_mutation]))
amusement /= 2;
- else if (mut_data[which_mutation].bad == MT_BAD)
+ else if (MUT_BAD(mut_data[which_mutation]))
amusement *= 2;
+ // currently is only ever one of these, but maybe that'll change?
return amusement;
}
-static bool _accept_mutation(mutation_type mutat, bool ignore_rarity = false)
+static bool _accept_mutation(mutation_type mutat, bool ignore_weight = false)
{
if (!_is_valid_mutation(mutat))
return false;
@@ -954,25 +974,50 @@ static bool _accept_mutation(mutation_type mutat, bool ignore_rarity = false)
if (you.mutation[mutat] >= mdef.levels)
return false;
- if (ignore_rarity)
+ if (ignore_weight)
return true;
- const int rarity = mdef.rarity + you.innate_mutation[mutat];
+ const int weight = mdef.weight + you.innate_mutation[mutat];
- // Low rarity means unlikely to choose it.
- return x_chance_in_y(rarity, 10);
+ // Low weight means unlikely to choose it.
+ return x_chance_in_y(weight, 10);
}
-static mutation_type _get_random_slime_mutation()
+static mutation_type _get_randmut(mut_use_type mt)
{
- const mutation_type slime_muts[] =
+ int cweight = random2(total_weight[mt]);
+ for (unsigned i = 0; i < ARRAYSZ(mut_data); ++i)
{
- MUT_GELATINOUS_BODY, MUT_EYEBALLS, MUT_TRANSLUCENT_SKIN,
- MUT_PSEUDOPODS, MUT_ACIDIC_BITE, MUT_TENDRILS,
- MUT_JELLY_GROWTH, MUT_JELLY_MISSILE
- };
+ if (!_mut_has_use(mut_data[i], mt))
+ continue;
+
+ cweight -= _mut_weight(mut_data[i], mt);
+ if (cweight >= 0)
+ continue;
+
+ if (_accept_mutation(mut_data[i].mutation, true))
+ return mut_data[i].mutation;
+ return NUM_MUTATIONS;
+ }
+
+ die("Error while selecting mutations");
+}
+
+static mutation_type _get_randmut_with_retries(mut_use_type mt)
+{
+ for (int attempt = 0; attempt < 100; ++attempt)
+ {
+ mutation_type mut = _get_randmut(mt);
+ if (mut != NUM_MUTATIONS)
+ return mut;
+ }
+
+ return NUM_MUTATIONS;
+}
- return RANDOM_ELEMENT(slime_muts);
+static mutation_type _get_random_slime_mutation()
+{
+ return _get_randmut(MU_USE_JIYVA);
}
static mutation_type _delete_random_slime_mutation()
@@ -998,21 +1043,11 @@ static mutation_type _delete_random_slime_mutation()
static bool _is_slime_mutation(mutation_type m)
{
- return m == MUT_GELATINOUS_BODY || m == MUT_EYEBALLS
- || m == MUT_TRANSLUCENT_SKIN || m == MUT_PSEUDOPODS
- || m == MUT_ACIDIC_BITE || m == MUT_TENDRILS
- || m == MUT_JELLY_GROWTH || m == MUT_JELLY_MISSILE;
+ return _mut_has_use(mut_data[mut_index[m]], MU_USE_JIYVA);
}
static mutation_type _get_random_xom_mutation()
{
- const mutation_type bad_muts[] =
- {
- MUT_WEAK, MUT_DOPEY,
- MUT_CLUMSY, MUT_DEFORMED, MUT_SCREAM,
- MUT_DETERIORATION, MUT_BLURRY_VISION, MUT_FRAIL
- };
-
mutation_type mutat = NUM_MUTATIONS;
do
@@ -1022,7 +1057,7 @@ static mutation_type _get_random_xom_mutation()
if (one_chance_in(1000))
return NUM_MUTATIONS;
else if (one_chance_in(5))
- mutat = RANDOM_ELEMENT(bad_muts);
+ mutat = _get_randmut(MU_USE_XOM);
}
while (!_accept_mutation(mutat, false));
@@ -1031,74 +1066,36 @@ static mutation_type _get_random_xom_mutation()
static mutation_type _get_random_corrupt_mutation()
{
- const mutation_type corrupt_muts[] =
- {
- MUT_DEFORMED, MUT_DETERIORATION, MUT_BLURRY_VISION,
- MUT_SLOW_HEALING, MUT_FRAIL, MUT_LOW_MAGIC,
- MUT_HEAT_VULNERABILITY,
- MUT_COLD_VULNERABILITY,
- MUT_FAST_METABOLISM
- };
-
- return RANDOM_ELEMENT(corrupt_muts);
+ return _get_randmut(MU_USE_CORRUPT);
}
static mutation_type _get_random_qazlal_mutation()
{
- const mutation_type qazlal_muts[] =
- {
- MUT_HEAT_VULNERABILITY,
- MUT_COLD_VULNERABILITY,
- MUT_SHOCK_VULNERABILITY,
- MUT_DEFORMED // in lieu of other ways to nuke AC
- };
-
- return RANDOM_ELEMENT(qazlal_muts);
+ return _get_randmut(MU_USE_QAZLAL);
}
static mutation_type _get_random_mutation(mutation_type mutclass)
{
- mut_total mt;
+ mut_use_type mt;
switch (mutclass)
{
case RANDOM_MUTATION:
// maintain an arbitrary ratio of good to bad muts to allow easier
// weight changes within categories - 60% good seems to be about
// where things are right now
- mt = x_chance_in_y(3, 5) ? MT_GOOD : MT_BAD;
+ mt = x_chance_in_y(3, 5) ? MU_USE_GOOD : MU_USE_BAD;
break;
case RANDOM_BAD_MUTATION:
- mt = MT_BAD;
+ mt = MU_USE_BAD;
break;
case RANDOM_GOOD_MUTATION:
- mt = MT_GOOD;
+ mt = MU_USE_GOOD;
break;
default:
die("invalid mutation class: %d", mutclass);
}
- int tries = 0;
-retry:
-
- int cweight = random2(total_rarity[mt]);
- for (unsigned i = 0; i < ARRAYSZ(mut_data); ++i)
- {
- // if the mut's badness isn't the kind we're looking for, skip it.
- if (mut_data[i].bad != (mt == MT_BAD)) // sorry :(
- continue;
-
- if ((cweight -= mut_data[i].rarity) >= 0)
- continue;
-
- if (_accept_mutation(mut_data[i].mutation, true))
- return mut_data[i].mutation;
-
- if (tries++ > 100)
- return NUM_MUTATIONS;
- goto retry;
- }
-
- die("mutation total changed???");
+ return _get_randmut_with_retries(mt);
}
// Tries to give you the mutation by deleting a conflicting
@@ -1696,7 +1693,6 @@ bool mutate(mutation_type which_mutation, const string &reason, bool failMsg,
break;
}
- // Amusement value will be 12 * (11-rarity) * Xom's-sense-of-humor.
xom_is_stimulated(_calc_mutation_amusement_value(mutat));
if (!temporary)
@@ -1888,12 +1884,14 @@ bool delete_mutation(mutation_type which_mutation, const string &reason,
const mutation_def& mdef = get_mutation_def(mutat);
- if (random2(10) >= mdef.rarity && !_is_slime_mutation(mutat))
+ if (random2(10) >= mdef.weight && !_is_slime_mutation(mutat))
continue;
const bool mismatch =
- (which_mutation == RANDOM_GOOD_MUTATION && mdef.bad)
- || (which_mutation == RANDOM_BAD_MUTATION && !mdef.bad);
+ (which_mutation == RANDOM_GOOD_MUTATION
+ && MUT_BAD(mdef))
+ || (which_mutation == RANDOM_BAD_MUTATION
+ && MUT_GOOD(mdef));
if (mismatch && (disallow_mismatch || !one_chance_in(10)))
continue;
@@ -2040,7 +2038,7 @@ string mutation_desc(mutation_type mut, int level, bool colour)
if (colour)
{
- const char* colourname = (mdef.bad ? "red" : "lightgrey");
+ const char* colourname = (MUT_BAD(mdef) ? "red" : "lightgrey");
const bool permanent = (you.innate_mutation[mut] > 0);
if (innate_upgrade)