This generator divides facets into body, awesome, great, and good ranks and assigns a fixed number of each.
6FBAIIDQLTXNSPYEEDV5ISD24S5F7PX2JOWEMXMS4LE53RC6T6EAC GVQ3WJYH5GSRIDSOP3KX7ZBDXT6SPSAAGBVD4WSB5UF25P3LGA4AC TJ544OJG4CFFMGMAQ2B7UJT432EIBUV5HOHDAQ7GMKZZKSDBFXZQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC 4LFTDJY3DK6S7C7SQLLML6UIZ42GZOWK2EIMZZSNEKBWSA3YNUZAC 3YX6L7FRX6HJVP6QX7VRWBJ6S2JZNRINKHOTPQGQAOGX2PS7H3JQC ZASKZI4USJSPW7CSCJUCFMLLTNQT3IGF5XSSW2FU7ESY735AMSFAC FI3VHM2VQ6464NMVYMZECJOR6QRAF34DFTY4QMZK6OKLULDPWDLQC CMNLYUECIMEZSOYG4KOSINOPER5OM7PPCGIHCM7LQVWEO77XFUYQC 63UCVTP63JTSBOG2SWB27RHOGKVSTRQL6XHF7D4GW2LNRDRZJ6FQC 3ZGWHU6PVOY4BN6RW6KDFDZMNRRVJUPPOKBJK6VGQWKCQO73RDLAC 2J7K5MBUMH2E7SP6QAG3NCWLKOAVCCXGBTOWBS4TFR62EPR5LCTQC 44HR7YI3CBRCEGEMIM6UOITU4W3RR5RBUGUV7ICXCN3ZIXLRJXYAC XT54K5UXLTCR4WIB6OWYISDRXLC4WXFAK5MHKUBCDKDIKQSLS6GAC TOYJHC7532L4YAJQZB7CL6VO5MAQW7JQ26TNFRDUMY4EP3S4NE3AC VUQ5XAUEMDXEZG6OSF5KATPGSKWG7O2FETTNENYVKZ5CCTJVWICQC 7C7OYEU7GMPWNWG6PKK6WLLTJGUDDX5IY6ABHTDYRQ3KY4T34IQAC UQ7N7BERCVCYALWKITQMJIWNSHHSWUYOU65LXD6HQKLXG4NF5CTAC CA6ZG6P2CE5EPAOQSB3P7NBDKTNFFHQP4CPOUFZL32ON6N32GSSQC 335BGGYD3NH4ACHUEZGDXKXXMVL6JMGQ7YPHLTU2256GT2VWV24AC TUK5T3O6YOMKR6SD37666MMV4OHXQ7D76JJ4DNVP5AXWZ2VQ2DXAC N7UOKHTWPOTV3OGAOCE2N6N6EOLBOBQ37CIR4LTE2LCEAUVGABBQC MUT_BONEY_PLATES, MUT_GREEN_SCALES, MUT_BLACK_SCALES,MUT_GREY_SCALES, MUT_RED_SCALES, MUT_NACREOUS_SCALES,MUT_GREY2_SCALES, MUT_METALLIC_SCALES, MUT_BLACK2_SCALES,MUT_WHITE_SCALES, MUT_YELLOW_SCALES, MUT_BROWN_SCALES,MUT_BLUE_SCALES, MUT_PURPLE_SCALES, MUT_SPECKLED_SCALES,MUT_ORANGE_SCALES, MUT_INDIGO_SCALES, MUT_RED2_SCALES,MUT_IRIDESCENT_SCALES, MUT_PATTERNED_SCALES};static int _is_covering(mutation_type mut){for (unsigned i = 0; i < ARRAYSZ(_all_scales); ++i)if (_all_scales[i] == mut)return 1;return 0;}
MUT_BONEY_PLATES, MUT_GREEN_SCALES, MUT_BLACK_SCALES,MUT_GREY_SCALES, MUT_RED_SCALES, MUT_NACREOUS_SCALES,MUT_GREY2_SCALES, MUT_METALLIC_SCALES, MUT_BLACK2_SCALES,MUT_WHITE_SCALES, MUT_YELLOW_SCALES, MUT_BROWN_SCALES,MUT_BLUE_SCALES, MUT_PURPLE_SCALES, MUT_SPECKLED_SCALES,MUT_ORANGE_SCALES, MUT_INDIGO_SCALES, MUT_RED2_SCALES,MUT_IRIDESCENT_SCALES, MUT_PATTERNED_SCALES};
mutation_type whichm = NUM_MUTATIONS;int counter = 0;powers++;// A demonspawn logically has six mutation slots, like [cold res,// negative res, teleport, black scales, mapping, repulsion field].// They all start at 0 levels. For a smooth power-up, when this// function is called we increase one mutation slot (which is not// already at 3) by 1 level only.// Look through the existing demon powers to find the slot. Note// that this will not find powers at level 0; if a new power needs// to be given, we will fall off the loop.int increasable_muts_seen = 0;int muts_seen = 0;mutation_type mut_to_increase = NUM_MUTATIONS;for (int i = 0; i < NUM_MUTATIONS; ++i){whichm = static_cast<mutation_type>(i);if (! muts[whichm]){continue;}++muts_seen;if (muts[whichm] < mutation_defs[whichm].levels){++increasable_muts_seen;
// First try for a body mutation; every DS has exactly one of these, as// they result in the loss or crippling of one slot, and we don't want to// deal with the balance issues of a variable-slot race.static const mutation_type body_muts[] = {MUT_CLAWS, MUT_HORNS};
if (one_chance_in(increasable_muts_seen)){mut_to_increase = whichm;}}}
// "Awesome" mutations are character defining; they have a major effect// on strategy in at least one branch.static const mutation_type awesome_muts[] = {MUT_HEAT_RESISTANCE, MUT_FAST, MUT_TELEPORT_AT_WILL, MUT_MAPPING,MUT_ROBUST, MUT_NEGATIVE_ENERGY_RESISTANCE, MUT_BLACK_SCALES,MUT_METALLIC_SCALES, MUT_RED2_SCALES};
// If you have less than 6 mutations, add chances to gain a new oneif (muts_seen < 6){int chances_to_get_new = 6 - muts_seen;
// "Great" mutations define strategy in common encounters, but not// universal.static const mutation_type great_muts[] = {MUT_REGENERATION, MUT_GREEN_SCALES, MUT_BLACK_SCALES,MUT_REPULSION_FIELD, MUT_MAGIC_RESISTANCE, MUT_BREATHE_FLAMES,MUT_NACREOUS_SCALES, MUT_GREY2_SCALES, MUT_BLACK2_SCALES,MUT_WHITE_SCALES, MUT_YELLOW_SCALES, MUT_BROWN_SCALES,MUT_PURPLE_SCALES, MUT_INDIGO_SCALES, MUT_COLD_RESISTANCE};
if (x_chance_in_y(chances_to_get_new, increasable_muts_seen)){mut_to_increase = NUM_MUTATIONS;}}
static const mutation_type good_muts[] = {MUT_TOUGH_SKIN, MUT_GREY_SCALES, MUT_BONEY_PLATES,MUT_SLOW_METABOLISM, MUT_SPIT_POISON, MUT_BLINK, MUT_SHAGGY_FUR,MUT_HIGH_MAGIC, MUT_RED_SCALES, MUT_BLUE_SCALES,MUT_SPECKLED_SCALES, MUT_ORANGE_SCALES, MUT_IRIDESCENT_SCALES,MUT_PATTERNED_SCALES};
// If you already have 6 demon powers, but there are no candidates// for increasing, then this function has been called too many times.// XXX right now, there are 1-level mutations on the demonspawn list,// so this will be reached - give a bonus power.
bool good_enough = false;
return mut_to_increase;}// Otherwise we're adding a brand new mutation
muts[0] = RANDOM_ELEMENT(body_muts);muts[1] = RANDOM_ELEMENT(awesome_muts);muts[2] = RANDOM_ELEMENT(great_muts);muts[3] = RANDOM_ELEMENT(great_muts);muts[4] = RANDOM_ELEMENT(good_muts);muts[5] = RANDOM_ELEMENT(good_muts);
// Merged the demonspawn lists into a single loop. Now a high-level// character can potentially get mutations from the low-level list// if it's having trouble with the high level list.do{if (level >= 10)
// Check for conflicting mutationsfor (int i = 0; i < 6; ++i)
if (1){ // good conjurers don't get bolt of drainingwhichm = MUT_SMITE;}if (one_chance_in(4)){ // good conjurers don't get hellfirewhichm = MUT_HURL_HELLFIRE;}// Makhlebites have the summonings invocationif (one_chance_in(3)){ // good summoners don't get summon demonwhichm = MUT_SUMMON_DEMONS;}if (one_chance_in(8)){whichm = MUT_MAGIC_RESISTANCE;}if (one_chance_in(12)){whichm = MUT_FAST;}if (one_chance_in(7)){whichm = MUT_TELEPORT_AT_WILL;}if (one_chance_in(10)){whichm = MUT_REGENERATION;}if (one_chance_in(12)){whichm = MUT_SHOCK_RESISTANCE;}if (!muts[MUT_CALL_TORMENT] && one_chance_in(15)){whichm = MUT_TORMENT_RESISTANCE;}if (one_chance_in(12))
for (int j = 0; j < i; ++j)
whichm = MUT_NEGATIVE_ENERGY_RESISTANCE;}if (!muts[MUT_TORMENT_RESISTANCE] && one_chance_in(20)){whichm = MUT_CALL_TORMENT;}if (one_chance_in(12)){whichm = MUT_CONTROL_DEMONS;}if (one_chance_in(11)){whichm = MUT_DEATH_STRENGTH;}if (one_chance_in(11)){whichm = MUT_CHANNEL_HELL;}
// No redundancy, pleaseif (muts[i] == muts[j])goto try_again;
if (one_chance_in(10)){whichm = MUT_RAISE_DEAD;}
// Prevent excessive scalesif (_is_covering(muts[i]) && _is_covering(muts[j]))goto try_again;
if (one_chance_in(25)){whichm = MUT_DRAIN_LIFE;
// Physiology conflictif ((muts[i] == MUT_SLOW_METABOLISM && muts[j] == MUT_REGENERATION)|| (muts[i] == MUT_REGENERATION && muts[j] == MUT_SLOW_METABOLISM))goto try_again;
if (!muts[MUT_THROW_FROST] // only one of these&& !muts[MUT_THROW_FLAMES]&& !muts[MUT_BREATHE_FLAMES]){whichm = (coinflip() ? MUT_THROW_FLAMES : MUT_THROW_FROST);}// summoners and Makhlebites don't get summon impif (one_chance_in(3)){whichm = (level < 10) ? MUT_SUMMON_MINOR_DEMONS: MUT_SUMMON_DEMONS;}if (one_chance_in(4)){whichm = MUT_POISON_RESISTANCE;}if (one_chance_in(4)){whichm = MUT_COLD_RESISTANCE;}if (one_chance_in(4)){whichm = MUT_HEAT_RESISTANCE;}if (one_chance_in(5)){whichm = MUT_ACUTE_VISION;}if (one_chance_in(7)){whichm = MUT_SPIT_POISON;}if (one_chance_in(10)){whichm = MUT_MAPPING;}if (one_chance_in(12)){whichm = MUT_TELEPORT_CONTROL;}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 (one_chance_in(12)){whichm = (level < 10) ? MUT_BLINK: MUT_TELEPORT_AT_WILL;}if (1){if (one_chance_in(10)){whichm = MUT_TOUGH_SKIN;}if (one_chance_in(24)){whichm = MUT_GREEN_SCALES;}if (one_chance_in(24)){whichm = MUT_BLACK_SCALES;}if (one_chance_in(24)){whichm = MUT_GREY_SCALES;}if (one_chance_in(12)){whichm = static_cast<mutation_type>(MUT_RED_SCALES +random2(16));}if (one_chance_in(30)){whichm = MUT_BONEY_PLATES;}}if (one_chance_in(25)){whichm = MUT_REPULSION_FIELD;}if (one_chance_in( (level < 10) ? 5 : 20 )){whichm = MUT_HORNS;}
facets[i][0] = facets[i][1] = facets[i][2] = muts[i];
mutation_type newmut = _demonspawn(muts, npowers, level);
int available_facets[6];int navailable_facets = 0;for (int i = 0; i < 6; ++i)if (given[i] != 3)available_facets[navailable_facets++] = i;int which_facet = available_facets[random2(navailable_facets)];mutation_type newmut = facets[which_facet][given[which_facet]];