summaryrefslogtreecommitdiffstats
path: root/trunk/source/mutation.cc
diff options
context:
space:
mode:
authorpeterb12 <peterb12@c06c8d41-db1a-0410-9941-cceddc491573>2005-07-21 02:34:44 +0000
committerpeterb12 <peterb12@c06c8d41-db1a-0410-9941-cceddc491573>2005-07-21 02:34:44 +0000
commit673bdae75485d14f759af597c3c62b99601f9a43 (patch)
tree368103f29fe0ce5dcf98060d9b5faa04590085fb /trunk/source/mutation.cc
parent7e900be770db24b0405fd2162491c405a425873e (diff)
downloadcrawl-ref-673bdae75485d14f759af597c3c62b99601f9a43.tar.gz
crawl-ref-673bdae75485d14f759af597c3c62b99601f9a43.zip
Initial revision
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'trunk/source/mutation.cc')
-rw-r--r--trunk/source/mutation.cc2326
1 files changed, 2326 insertions, 0 deletions
diff --git a/trunk/source/mutation.cc b/trunk/source/mutation.cc
new file mode 100644
index 0000000000..036d624fb9
--- /dev/null
+++ b/trunk/source/mutation.cc
@@ -0,0 +1,2326 @@
+/*
+ * File: mutation.cc
+ * Summary: Functions for handling player mutations.
+ * Written by: Linley Henzell
+ *
+ * Change History (most recent first):
+ *
+ * <5> 7/29/00 JDJ Made give_cosmetic_mutation static
+ * <4> 9/25/99 CDL linuxlib -> liblinux
+ * <3> 9/21/99 LRH Added many new scales
+ * <2> 5/20/99 BWR Fixed it so demonspwan should
+ * always get a mutation, 3 level
+ * perma_mutations now work.
+ * <1> -/--/-- LRH Created
+ */
+
+#include "AppHdr.h"
+#include "mutation.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DOS
+#include <conio.h>
+#endif
+
+#ifdef LINUX
+#include "liblinux.h"
+#endif
+
+#include "externs.h"
+
+#include "defines.h"
+#include "effects.h"
+#include "macro.h"
+#include "ouch.h"
+#include "player.h"
+#include "skills2.h"
+#include "stuff.h"
+#include "transfor.h"
+#include "view.h"
+
+
+int how_mutated(void);
+char body_covered(void);
+bool perma_mutate(int which_mut, char how_much);
+
+const char *mutation_descrip[][3] = {
+ {"You have tough skin (AC +1).", "You have very tough skin (AC +2).",
+ "You have extremely tough skin (AC +3)."},
+
+ {"Your muscles are strong (Str +", "", ""},
+ {"Your mind is acute (Int +", "", ""},
+ {"You are agile (Dex +", "", ""},
+
+ {"You are partially covered in green scales (AC + 1).",
+ "You are mostly covered in green scales (AC + 3).",
+ "You are covered in green scales (AC + 5)."},
+
+ {"You are partially covered in thick black scales (AC + 3, dex - 1).",
+ "You are mostly covered in thick black scales (AC + 6, dex - 2).",
+ "You are completely covered in thick black scales (AC + 9, dex - 3)."},
+
+ {"You are partially covered in supple grey scales (AC + 1).",
+ "You are mostly covered in supple grey scales (AC + 2).",
+ "You are completely covered in supple grey scales (AC + 3)."},
+
+ {"You are protected by plates of bone (AC + 2, dex - 1).",
+ "You are protected by plates of bone (AC + 3, dex - 2).",
+ "You are protected by plates of bone (AC + 4, dex - 3)."},
+
+ {"You are surrounded by a mild repulsion field (ev + 1).",
+ "You are surrounded by a moderate repulsion field (ev + 3).",
+ "You are surrounded by a strong repulsion field (ev + 5; repel missiles)."},
+ {"Your system is immune to poisons.", "Your system is immune to poisons.",
+ "Your system is immune to poisons."},
+// 10
+
+ {"Your digestive system is specialised to digest meat.",
+ "Your digestive system is specialised to digest meat.",
+ "You are primarily a carnivore."},
+
+ {"You digest meat inefficiently.", "You digest meat inefficiently.",
+ "You are primarily a herbivore."},
+
+ {"Your flesh is heat resistant.", "Your flesh is very heat resistant.",
+ "Your flesh is almost immune to the effects of heat."},
+
+ {"Your flesh is cold resistant.", "Your flesh is very cold resistant.",
+ "Your flesh is almost immune to the effects of cold."},
+
+ {"You are immune to electric shocks.", "You are immune to electric shocks.",
+ "You are immune to electric shocks."},
+
+ {"Your natural rate of healing is unusually fast.",
+ "You heal very quickly.",
+ "You regenerate."},
+
+ {"You have a fast metabolism.", "You have a very fast metabolism.",
+ "Your metabolism is lightning-fast."},
+
+ {"You have a slow metabolism.", "You have a slow metabolism.",
+ "You need consume almost no food."},
+
+ {"You are weak (Str -", "", ""},
+ {"You are dopey (Int -", "", ""},
+// 20
+ {"You are clumsy (Dex -", "", ""},
+
+ {"You can control translocations.", "You can control translocations.",
+ "You can control translocations."},
+
+ {"Space occasionally distorts in your vicinity.",
+ "Space sometimes distorts in your vicinity.",
+ "Space frequently distorts in your vicinity."},
+
+ {"You are resistant to magic.", "You are highly resistant to magic.",
+ "You are extremely resistant to the effects of magic."},
+
+ {"You cover the ground quickly.", "You cover the ground very quickly.",
+ "You cover the ground extremely quickly."},
+
+ {"You have supernaturally acute eyesight.",
+ "You have supernaturally acute eyesight.",
+ "You have supernaturally acute eyesight."},
+
+ {"Armour fits poorly on your deformed body.",
+ "Armour fits poorly on your badly deformed body.",
+ "Armour fits poorly on your hideously deformed body."},
+
+ {"You can teleport at will.", "You are good at teleporting at will.",
+ "You can teleport instantly at will."},
+
+ {"You can spit poison.", "You can spit poison.", "You can spit poison."},
+
+ {"You can sense your immediate surroundings.",
+ "You can sense your surroundings.",
+ "You can sense a large area of your surroundings."},
+
+// 30
+
+ {"You can breathe flames.", "You can breathe fire.",
+ "You can breathe blasts of fire."},
+
+ {"You can translocate small distances instantaneously.",
+ "You can translocate small distances instantaneously.",
+ "You can translocate small distances instantaneously."},
+
+ {"You have a pair of small horns on your head.",
+ "You have a pair of horns on your head.",
+ "You have a pair of large horns on your head."},
+
+ {"Your muscles are strong (Str +1), but stiff (Dex -1).",
+ "Your muscles are very strong (Str +2), but stiff (Dex -2).",
+ "Your muscles are extremely strong (Str +3), but stiff (Dex -3)."},
+
+ {"Your muscles are flexible (Dex +1), but weak (Str -1).",
+ "Your muscles are very flexible (Dex +2), but weak (Str -2).",
+ "Your muscles are extremely flexible (Dex +3), but weak (Str -3)."},
+
+ {"You occasionally forget where you are.",
+ "You sometimes forget where you are.",
+ "You frequently forget where you are."},
+
+ {"You possess an exceptional clarity of mind.",
+ "You possess an unnatural clarity of mind.",
+ "You possess a supernatural clarity of mind."},
+
+ {"You tend to lose your temper in combat.",
+ "You often lose your temper in combat.",
+ "You have an uncontrollable temper."},
+
+ {"Your body is slowly deteriorating.", "Your body is deteriorating.",
+ "Your body is rapidly deteriorating."},
+
+ {"Your vision is a little blurry.", "Your vision is quite blurry.",
+ "Your vision is extremely blurry."},
+// 40
+
+ {"You are somewhat resistant to further mutation.",
+ "You are somewhat resistant to both further mutation and mutation removal.",
+ "Your current mutations are irrevocably fixed, and you can mutate no more."},
+
+ {"You are frail (-10 percent hp).", "You are very frail (-20 percent hp).",
+ "You are extremely frail (-30 percent hp)."},
+
+ {"You are robust (+10 percent hp).",
+ "You are very robust (+20 percent hp).",
+ "You are extremely robust (+30 percent hp)."},
+
+ {"You are immune to unholy pain and torment.", "", ""},
+
+ {"You resist negative energy.",
+ "You are quite resistant to negative energy.",
+ "You are immune to negative energy."},
+
+ /* Use player_has_spell() to avoid duplication */
+ {"You can summon minor demons to your aid.", "", ""},
+ {"You can summon demons to your aid.", "", ""},
+ {"You can hurl blasts of hellfire.", "", ""},
+ {"You can call on the torments of Hell.", "", ""},
+ {"You can raise the dead to walk for you.", "", ""},
+// 50
+ {"You can control demons.", "", ""},
+ {"You can travel to (but not from) Pandemonium at will.", "", ""},
+ {"You can draw strength from death and destruction.", "", ""},
+
+ /* Not worshippers of Vehumet */
+ {"You can channel magical energy from Hell.", "", ""},
+
+ {"You can drain life in unarmed combat.", "", ""},
+
+ /* Not conjurers/worshippers of Makhleb */
+ {"You can throw forth the flames of Gehenna.", "", ""},
+
+ {"You can throw forth the frost of Cocytus.", "", ""},
+
+ {"You can invoke the powers of Tartarus to smite your living foes.", "", ""},
+ {"You have sharp fingernails.", "Your fingernails are very sharp.",
+ "You have claws for hands."},
+
+ {"You have hooves in place of feet.", "", ""},
+ // 60 - leave some space for more demonic powers...
+ {"You can exhale a cloud of poison.", "", ""},
+
+ {"Your tail ends in a poisonous barb.",
+ "Your tail ends in a sharp poisonous barb.",
+ "Your tail ends in a wicked poisonous barb."}, //jmf: nagas & dracos
+
+ {"Your wings are large and strong.", "", ""}, //jmf: dracos only
+
+ //jmf: these next two are for evil gods to mark their followers; good gods
+ // will never accept a 'marked' worhsipper
+
+ {"There is a blue sigil on each of your hands.",
+ "There are several blue sigils on your hands and arms.",
+ "Your hands, arms and shoulders are covered in intricate, arcane blue writing."},
+
+ {"There is a green sigil on your chest.",
+ "There are several green sigils on your chest and abdomen.",
+ "Your chest, abdomen and neck are covered in intricate, arcane green writing."},
+
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ // 70
+
+ {"You are partially covered in red scales (AC + 1).",
+ "You are mostly covered in red scales (AC + 2).",
+ "You are covered in red scales (AC + 4)."},
+
+ {"You are partially covered in smooth nacreous scales (AC + 1).",
+ "You are mostly covered in smooth nacreous scales (AC + 3).",
+ "You are completely covered in smooth nacreous scales (AC + 5)."},
+
+ {"You are partially covered in ridged grey scales (AC + 2, dex - 1).",
+ "You are mostly covered in ridged grey scales (AC + 4, dex - 1).",
+ "You are completely covered in ridged grey scales (AC + 6, dex - 2)."},
+
+ {"You are partially covered in metallic scales (AC + 3, dex - 2).",
+ "You are mostly covered in metallic scales (AC + 7, dex - 3).",
+ "You are completely covered in metallic scales (AC + 10, dex - 4)."},
+
+ {"You are partially covered in black scales (AC + 1).",
+ "You are mostly covered in black scales (AC + 3).",
+ "You are completely covered in black scales (AC + 5)."},
+
+ {"You are partially covered in white scales (AC + 1).",
+ "You are mostly covered in white scales (AC + 3).",
+ "You are completely covered in white scales (AC + 5)."},
+
+ {"You are partially covered in yellow scales (AC + 2).",
+ "You are mostly covered in yellow scales (AC + 4, dex - 1).",
+ "You are completely covered in yellow scales (AC + 6, dex - 2)."},
+
+ {"You are partially covered in brown scales (AC + 2).",
+ "You are mostly covered in brown scales (AC + 4).",
+ "You are completely covered in brown scales (AC + 5)."},
+
+ {"You are partially covered in blue scales (AC + 1).",
+ "You are mostly covered in blue scales (AC + 2).",
+ "You are completely covered in blue scales (AC + 3)."},
+
+ {"You are partially covered in purple scales (AC + 2).",
+ "You are mostly covered in purple scales (AC + 4).",
+ "You are completely covered in purple scales (AC + 6)."},
+
+// 80
+
+ {"You are partially covered in speckled scales (AC + 1).",
+ "You are mostly covered in speckled scales (AC + 2).",
+ "You are covered in speckled scales (AC + 3)."},
+
+ {"You are partially covered in orange scales (AC + 1).",
+ "You are mostly covered in orange scales (AC + 3).",
+ "You are completely covered in orange scales (AC + 4)."},
+
+ {"You are partially covered in indigo scales (AC + 2).",
+ "You are mostly covered in indigo scales (AC + 3).",
+ "You are completely covered in indigo scales (AC + 5)."},
+
+ {"You are partially covered in knobbly red scales (AC + 2).",
+ "You are mostly covered in knobbly red scales (AC + 5, dex - 1).",
+ "You are completely covered in knobbly red scales (AC + 7, dex - 2)."},
+
+ {"You are partially covered in iridescent scales (AC + 1).",
+ "You are mostly covered in iridescent scales (AC + 2).",
+ "You are completely covered in iridescent scales (AC + 3)."},
+
+ {"You are partially covered in patterned scales (AC + 1).",
+ "You are mostly covered in patterned scales (AC + 2).",
+ "You are completely covered in patterned scales (AC + 3)."},
+};
+
+/*
+ If giving a mutation which must succeed (eg demonspawn), must add exception
+ to the "resist mutation" mutation thing.
+ */
+
+const char *gain_mutation[][3] = {
+ {"Your skin toughens.", "Your skin toughens.", "Your skin toughens."},
+
+ {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
+ {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
+ {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
+
+ {"Green scales grow over part of your body.",
+ "Green scales spread over more of your body.",
+ "Green scales cover you completely."},
+
+ {"Thick black scales grow over part of your body.",
+ "Thick black scales spread over more of your body.",
+ "Thick black scales cover you completely."},
+
+ {"Supple grey scales grow over part of your body.",
+ "Supple grey scales spread over more of your body.",
+ "Supple grey scales cover you completely."},
+
+ {"You grow protective plates of bone.",
+ "You grow more protective plates of bone.",
+ "You grow more protective plates of bone."},
+
+ {"You begin to radiate repulsive energy.",
+ "Your repulsive radiation grows stronger.",
+ "Your repulsive radiation grows stronger."},
+
+ {"You feel healthy.", "You feel healthy.", "You feel healthy."},
+// 10
+ {"You hunger for flesh.", "You hunger for flesh.", "You hunger for flesh."},
+
+ {"You hunger for vegetation.", "You hunger for vegetation.",
+ "You hunger for vegetation."},
+
+ {"You feel a sudden chill.", "You feel a sudden chill.",
+ "You feel a sudden chill."},
+
+ {"You feel hot for a moment.", "You feel hot for a moment.",
+ "You feel hot for a moment."},
+
+ {"You feel insulated.", "You feel insulated.", "You feel insulated."},
+
+ {"You begin to heal more quickly.",
+ "You begin to heal more quickly.",
+ "You begin to regenerate."},
+
+ {"You feel a little hungry.", "You feel a little hungry.",
+ "You feel a little hungry."},
+
+ {"Your metabolism slows.", "Your metabolism slows.",
+ "Your metabolism slows."},
+
+ {"You feel weaker.", "You feel weaker.", "You feel weaker."},
+
+ {"You feel less intelligent.", "You feel less intelligent",
+ "You feel less intelligent"},
+// 20
+ {"You feel clumsy.", "You feel clumsy.",
+ "You feel clumsy."},
+
+ {"You feel controlled.", "You feel controlled.",
+ "You feel controlled."},
+
+ {"You feel weirdly uncertain.",
+ "You feel even more weirdly uncertain.",
+ "You feel even more weirdly uncertain."},
+
+ {"You feel resistant to magic.",
+ "You feel more resistant to magic.",
+ "You feel almost impervious to the effects of magic."},
+
+ {"You feel quick.", "You feel quick.", "You feel quick."},
+
+ {"Your vision sharpens.", "Your vision sharpens.", "Your vision sharpens."},
+
+ {"Your body twists and deforms.", "Your body twists and deforms.",
+ "Your body twists and deforms."},
+
+ {"You feel jumpy.", "You feel more jumpy.", "You feel even more jumpy."},
+
+ {"There is a nasty taste in your mouth for a moment.",
+ "There is a nasty taste in your mouth for a moment.",
+ "There is a nasty taste in your mouth for a moment."},
+
+ {"You feel aware of your surroundings.",
+ "You feel more aware of your surroundings.",
+ "You feel even more aware of your surroundings."},
+// 30
+
+ {"Your throat feels hot.", "Your throat feels hot.",
+ "Your throat feels hot."},
+
+ {"You feel a little jumpy.", "You feel more jumpy.",
+ "You feel even more jumpy."},
+
+ {"A pair of horns grows on your head!",
+ "The horns on your head grow some more.",
+ "The horns on your head grow some more."},
+
+ {"Your muscles feel sore.", "Your muscles feel sore.",
+ "Your muscles feel sore."},
+
+ {"Your muscles feel loose.", "Your muscles feel loose.",
+ "Your muscles feel loose."},
+
+ {"You feel a little disoriented.", "You feel a little disoriented.",
+ "Where the Hells are you?"},
+
+ {"Your thoughts seem clearer.", "Your thoughts seem clearer.",
+ "Your thoughts seem clearer."},
+
+ {"You feel a little pissed off.", "You feel angry.",
+ "You feel extremely angry at everything!"},
+
+ {"You feel yourself wasting away.", "You feel yourself wasting away.",
+ "You feel your body start to fall apart."},
+
+ {"Your vision blurs.", "Your vision blurs.", "Your vision blurs."},
+// 40
+
+ {"You feel genetically stable.", "You feel genetically stable.",
+ "You feel genetically immutable."},
+
+ {"You feel frail.", "You feel frail.", "You feel frail."},
+ {"You feel robust.", "You feel robust.", "You feel robust."},
+ {"You feel a strange anaesthesia.", "", ""},
+ {"You feel negative.", "You feel negative.", "You feel negative."},
+ {"A thousand chattering voices call out to you.", "", ""},
+ {"Help is not far away!", "", ""},
+ {"You smell fire and brimstone.", "", ""},
+ {"You feel a terrifying power at your call.", "", ""},
+ {"You feel an affinity for the dead.", "", ""},
+// 50
+ {"You feel an affinity for all demonkind.", "", ""},
+ {"You feel something pulling you to a strange and terrible place.", "", ""},
+ {"You feel hungry for death.", "", ""},
+ {"You feel a flux of magical energy.", "", ""},
+ {"Your skin tingles in a strangely unpleasant way.", "", ""},
+ {"You smell the fires of Gehenna.", "", ""},
+ {"You feel the icy cold of Cocytus chill your soul.", "", ""},
+ {"A shadow passes over the world around you.", "", ""},
+
+ {"Your fingernails lengthen.", "Your fingernails sharpen.",
+ "Your hands twist into claws."},
+
+ {"Your feet shrivel into cloven hooves.", "", ""},
+ // 60
+
+ {"You taste something nasty.", "You taste something very nasty.",
+ "You taste something extremely nasty."},
+
+ {"A poisonous barb forms on the end of your tail.",
+ "The barb on your tail looks sharper.",
+ "The barb on your tail looks very sharp."},
+
+ {"Your wings grow larger and stronger.", "", ""},
+
+ {"Your hands itch.", "Your hands and forearms itch.",
+ "Your arms, hands and shoulders itch."},
+
+ {"Your chest itches.", "Your chest and abdomen itch.",
+ "Your chest, abdomen and neck itch."},
+
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ // 70
+
+ {"Red scales grow over part of your body.",
+ "Red scales spread over more of your body.",
+ "Red scales cover you completely."},
+ {"Smooth nacreous scales grow over part of your body.",
+ "Smooth nacreous scales spread over more of your body.",
+ "Smooth nacreous scales cover you completely."},
+ {"Ridged grey scales grow over part of your body.",
+ "Ridged grey scales spread over more of your body.",
+ "Ridged grey scales cover you completely."},
+ {"Metallic scales grow over part of your body.",
+ "Metallic scales spread over more of your body.",
+ "Metallic scales cover you completely."},
+ {"Black scales grow over part of your body.",
+ "Black scales spread over more of your body.",
+ "Black scales cover you completely."},
+ {"White scales grow over part of your body.",
+ "White scales spread over more of your body.",
+ "White scales cover you completely."},
+ {"Yellow scales grow over part of your body.",
+ "Yellow scales spread over more of your body.",
+ "Yellow scales cover you completely."},
+ {"Brown scales grow over part of your body.",
+ "Brown scales spread over more of your body.",
+ "Brown scales cover you completely."},
+ {"Blue scales grow over part of your body.",
+ "Blue scales spread over more of your body.",
+ "Blue scales cover you completely."},
+ {"Purple scales grow over part of your body.",
+ "Purple scales spread over more of your body.",
+ "Purple scales cover you completely."},
+ // 80
+
+ {"Speckled scales grow over part of your body.",
+ "Speckled scales spread over more of your body.",
+ "Speckled scales cover you completely."},
+ {"Orange scales grow over part of your body.",
+ "Orange scales spread over more of your body.",
+ "Orange scales cover you completely."},
+ {"Indigo scales grow over part of your body.",
+ "Indigo scales spread over more of your body.",
+ "Indigo scales cover you completely."},
+ {"Knobbly red scales grow over part of your body.",
+ "Knobbly red scales spread over more of your body.",
+ "Knobbly red scales cover you completely."},
+ {"Iridescent scales grow over part of your body.",
+ "Iridescent scales spread over more of your body.",
+ "Iridescent scales cover you completely."},
+ {"Patterned scales grow over part of your body.",
+ "Patterned scales spread over more of your body.",
+ "Patterned scales cover you completely."},
+};
+
+const char *lose_mutation[][3] = {
+
+ {"Your skin feels delicate.", "Your skin feels delicate.",
+ "Your skin feels delicate."},
+
+ {"You feel weaker.", "You feel weaker.", "You feel weaker."},
+
+ {"You feel less intelligent.", "You feel less intelligent",
+ "You feel less intelligent"},
+
+ {"You feel clumsy.", "You feel clumsy.", "You feel clumsy."},
+
+ {"Your green scales disappear.",
+ "Your green scales recede somewhat.",
+ "Your green scales recede somewhat."},
+
+ {"Your black scales disappear.", "Your black scales recede somewhat.",
+ "Your black scales recede somewhat."},
+
+ {"Your grey scales disappear.", "Your grey scales recede somewhat.",
+ "Your grey scales recede somewhat."},
+
+ {"Your bony plates shrink away.", "Your bony plates shrink.",
+ "Your bony plates shrink."},
+
+ {"You feel attractive.", "You feel attractive.", "You feel attractive."},
+
+ {"You feel a little less healthy.", "You feel a little less healthy.",
+ "You feel a little less healthy."},
+
+ {"You feel able to eat a more balanced diet.",
+ "You feel able to eat a more balanced diet.",
+ "You feel able to eat a more balanced diet."},
+
+ {"You feel able to eat a more balanced diet.",
+ "You feel able to eat a more balanced diet.",
+ "You feel able to eat a more balanced diet."},
+
+ {"You feel hot for a moment.", "You feel hot for a moment.",
+ "You feel hot for a moment."},
+
+ {"You feel a sudden chill.", "You feel a sudden chill.",
+ "You feel a sudden chill."},
+
+ {"You feel conductive.", "You feel conductive.", "You feel conductive."},
+
+ {"Your rate of healing slows.", "Your rate of healing slows.",
+ "Your rate of healing slows."},
+
+ {"Your metabolism slows.", "Your metabolism slows.",
+ "Your metabolism slows."},
+
+ {"You feel a little hungry.", "You feel a little hungry.",
+ "You feel a little hungry."},
+
+ {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
+ {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
+// 20
+ {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
+
+ {"You feel random.", "You feel uncontrolled.", "You feel uncontrolled."},
+ {"You feel stable.", "You feel stable.", "You feel stable."},
+
+ {"You feel less resistant to magic.", "You feel less resistant to magic.",
+ "You feel vulnerable to magic again."},
+
+ {"You feel sluggish.", "You feel sluggish.", "You feel sluggish."},
+
+ {"Your vision seems duller.", "Your vision seems duller.",
+ "Your vision seems duller."},
+
+ {"Your body's shape seems more normal.",
+ "Your body's shape seems slightly more normal.",
+ "Your body's shape seems slightly more normal."},
+
+ {"You feel static.", "You feel less jumpy.", "You feel less jumpy."},
+
+ {"You feel an ache in your throat.",
+ "You feel an ache in your throat.", "You feel an ache in your throat."},
+
+ {"You feel slightly disorientated.", "You feel slightly disorientated.",
+ "You feel slightly disorientated."},
+// 30
+
+ {"A chill runs up and down your throat.",
+ "A chill runs up and down your throat.",
+ "A chill runs up and down your throat."},
+
+ {"You feel a little less jumpy.", "You feel less jumpy.",
+ "You feel less jumpy."},
+
+ {"The horns on your head shrink away.",
+ "The horns on your head shrink a bit.",
+ "The horns on your head shrink a bit."},
+
+ {"Your muscles feel loose.", "Your muscles feel loose.",
+ "Your muscles feel loose."},
+
+ {"Your muscles feel sore.", "Your muscles feel sore.",
+ "Your muscles feel sore."},
+
+ {"You feel less disoriented.", "You feel less disoriented.",
+ "You feel less disoriented."},
+
+ {"Your thinking seems confused.", "Your thinking seems confused.",
+ "Your thinking seems confused."},
+
+ {"You feel a little more calm.", "You feel a little less angry.",
+ "You feel a little less angry."},
+
+ {"You feel healthier.", "You feel a little healthier.",
+ "You feel a little healthier."},
+
+ {"Your vision sharpens.", "Your vision sharpens a little.",
+ "Your vision sharpens a little."},
+// 40
+
+ {"You feel genetically unstable.", "You feel genetically unstable.",
+ "You feel genetically unstable."},
+
+ {"You feel robust.", "You feel robust.", "You feel robust."},
+ {"You feel frail.", "You feel frail.", "You feel frail."},
+
+/* Some demonic powers (which can't be lost) start here... */
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+// 50
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+
+ {"Your fingernails shrink to normal size.",
+ "Your fingernails look duller.", "Your hands feel fleshier."},
+
+ {"Your hooves expand and flesh out into feet!", "", ""},
+ // 60
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+ {"", "", ""},
+// 70
+
+ {"Your red scales disappear.", "Your red scales recede somewhat.",
+ "Your red scales recede somewhat."},
+
+ {"Your smooth nacreous scales disappear.",
+ "Your smooth nacreous scales recede somewhat.",
+ "Your smooth nacreous scales recede somewhat."},
+
+ {"Your ridged grey scales disappear.",
+ "Your ridged grey scales recede somewhat.",
+ "Your ridged grey scales recede somewhat."},
+
+ {"Your metallic scales disappear.",
+ "Your metallic scales recede somewhat.",
+ "Your metallic scales recede somewhat."},
+
+ {"Your black scales disappear.", "Your black scales recede somewhat.",
+ "Your black scales recede somewhat."},
+
+ {"Your white scales disappear.", "Your white scales recede somewhat.",
+ "Your white scales recede somewhat."},
+
+ {"Your yellow scales disappear.", "Your yellow scales recede somewhat.",
+ "Your yellow scales recede somewhat."},
+
+ {"Your brown scales disappear.", "Your brown scales recede somewhat.",
+ "Your brown scales recede somewhat."},
+
+ {"Your blue scales disappear.", "Your blue scales recede somewhat.",
+ "Your blue scales recede somewhat."},
+
+ {"Your purple scales disappear.", "Your purple scales recede somewhat.",
+ "Your purple scales recede somewhat."},
+// 80
+
+ {"Your speckled scales disappear.",
+ "Your speckled scales recede somewhat.",
+ "Your speckled scales recede somewhat."},
+
+ {"Your orange scales disappear.", "Your orange scales recede somewhat.",
+ "Your orange scales recede somewhat."},
+
+ {"Your indigo scales disappear.", "Your indigo scales recede somewhat.",
+ "Your indigo scales recede somewhat."},
+
+ {"Your knobbly red scales disappear.",
+ "Your knobbly red scales recede somewhat.",
+ "Your knobbly red scales recede somewhat."},
+
+ {"Your iridescent scales disappear.",
+ "Your iridescent scales recede somewhat.",
+ "Your iridescent scales recede somewhat."},
+
+ {"Your patterned scales disappear.",
+ "Your patterned scales recede somewhat.",
+ "Your patterned scales recede somewhat."},
+};
+
+/*
+ Chance out of 10 that mutation will be given/removed randomly. 0 means never.
+ */
+const char mutation_rarity[] = {
+ 10, // tough skin
+ 8, // str
+ 8, // int
+ 8, // dex
+ 2, // gr scales
+ 1, // bl scales
+ 2, // grey scales
+ 1, // bone
+ 1, // repuls field
+ 4, // res poison
+// 10
+ 5, // carn
+ 5, // herb
+ 4, // res fire
+ 4, // res cold
+ 2, // res elec
+ 3, // regen
+ 10, // fast meta
+ 7, // slow meta
+ 10, // abil loss
+ 10, // ""
+// 20
+ 10, // ""
+ 2, // tele control
+ 3, // teleport
+ 5, // res magic
+ 1, // run
+ 2, // see invis
+ 8, // deformation
+ 2, // teleport at will
+ 8, // spit poison
+ 3, // sense surr
+// 30
+ 4, // breathe fire
+ 3, // blink
+ 7, // horns
+ 10, // strong/stiff muscles
+ 10, // weak/loose muscles
+ 6, // forgetfulness
+ 6, // clarity (as the amulet)
+ 7, // berserk/temper
+ 10, // deterioration
+ 10, // blurred vision
+// 40
+ 4, // resist mutation
+ 10, // frail
+ 5, // robust
+/* Some demonic powers start here: */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+// 50
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2, //jmf: claws
+ 1, //jmf: hooves
+// 60
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+// 70
+ 2, // red scales
+ 1, // nac scales
+ 2, // r-grey scales
+ 1, // metal scales
+ 2, // black scales
+ 2, // wh scales
+ 2, // yel scales
+ 2, // brown scales
+ 2, // blue scales
+ 2, // purple scales
+// 80
+ 2, // speckled scales
+ 2, // orange scales
+ 2, // indigo scales
+ 1, // kn red scales
+ 1, // irid scales
+ 1, // pattern scales
+ 0, //
+ 0, //
+ 0, //
+ 0 //
+};
+
+void display_mutations(void)
+{
+ int i;
+ int j = 0;
+ const char *mut_title = "Innate abilities, Weirdness & Mutations";
+ const int num_lines = get_number_of_lines();
+
+#ifdef DOS_TERM
+ char buffer[4800];
+
+ window(1, 1, 80, 25);
+ gettext(1, 1, 80, 25, buffer);
+#endif
+
+ clrscr();
+ textcolor(WHITE);
+
+ // center title
+ i = 40 - strlen(mut_title) / 2;
+ if (i<1) i=1;
+ gotoxy(i, 1);
+ cprintf(mut_title);
+ gotoxy(1,3);
+ textcolor(LIGHTBLUE); //textcolor for inborn abilities and weirdness
+
+ switch (you.species) //mv: following code shows innate abilities - if any
+ {
+ case SP_MERFOLK:
+ cprintf("You revert to your normal form in water." EOL);
+ j++;
+ break;
+
+ case SP_NAGA:
+ // breathe poison replaces spit poison:
+ if (!you.mutation[MUT_BREATHE_POISON])
+ cprintf("You can spit poison." EOL);
+ else
+ cprintf("You can exhale a cloud of poison." EOL);
+
+ cprintf("Your system is immune to poisons." EOL);
+ cprintf("You can see invisible." EOL);
+ j += 3;
+ break;
+
+ case SP_GNOME:
+ cprintf("You can sense your surroundings." EOL);
+ j++;
+ break;
+
+ case SP_TROLL:
+ cprintf("Your body regenerates quickly." EOL);
+ j++;
+ break;
+
+ case SP_GHOUL:
+ cprintf("Your body is rotting away." EOL);
+ cprintf("You are carnivorous." EOL);
+ j += 2;
+ break;
+
+ case SP_KOBOLD:
+ cprintf("You are carnivorous." EOL);
+ j++;
+ break;
+
+ case SP_GREY_ELF:
+ if (you.experience_level > 4)
+ {
+ cprintf("You are very charming." EOL);
+ j++;
+ }
+ break;
+
+ case SP_KENKU:
+ if (you.experience_level > 4)
+ {
+ cprintf("You can fly");
+ cprintf((you.experience_level > 14) ? " continuously." EOL : "."
+ EOL);
+ j++;
+ }
+ break;
+
+ case SP_MUMMY:
+ cprintf("You are");
+ cprintf((you.experience_level > 25) ? " very strongly" :
+ ((you.experience_level > 12) ? " strongly" : ""));
+ cprintf(" in touch with the powers of death." EOL);
+ j++;
+
+ if (you.experience_level >= 12)
+ {
+ cprintf("You can restore your body by infusing magical energy." EOL);
+ j++;
+ }
+ break;
+
+ case SP_GREEN_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You are resistant to poison." EOL);
+ cprintf("You can breathe poison." EOL);
+ j += 2;
+ }
+ break;
+
+ case SP_RED_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can breathe fire." EOL);
+ j++;
+ }
+ if (you.experience_level > 17)
+ {
+ cprintf("You are resistant to fire." EOL);
+ j++;
+ }
+ break;
+
+ case SP_WHITE_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can breathe frost." EOL);
+ j++;
+ }
+ if (you.experience_level > 17)
+ {
+ cprintf("You are resistant to cold." EOL);
+ j++;
+ }
+ break;
+
+ case SP_BLACK_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can breathe lightning." EOL);
+ j++;
+ }
+ if (you.experience_level > 17)
+ {
+ cprintf("You are resistant to lightning." EOL);
+ j++;
+ }
+ break;
+
+ case SP_GOLDEN_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can spit acid." EOL);
+ j++;
+ }
+ break;
+
+ case SP_PURPLE_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can breathe power." EOL);
+ j++;
+ }
+ break;
+
+ case SP_MOTTLED_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can breathe sticky flames." EOL);
+ j++;
+ }
+ break;
+
+ case SP_PALE_DRACONIAN:
+ if (you.experience_level > 6)
+ {
+ cprintf("You can breathe steam." EOL);
+ j++;
+ }
+ break;
+ } //end switch - innate abilities
+
+ textcolor(LIGHTGREY);
+
+ for (i = 0; i < 100; i++)
+ {
+ if (you.mutation[i] != 0)
+ {
+ // this is already handled above:
+ if (you.species == SP_NAGA && i == MUT_BREATHE_POISON)
+ continue;
+
+ j++;
+ textcolor(LIGHTGREY);
+
+ if (j > num_lines - 4)
+ {
+ gotoxy( 1, num_lines - 1 );
+ cprintf("-more-");
+
+ if (getch() == 0)
+ getch();
+
+ clrscr();
+
+ // center title
+ int x = 40 - strlen(mut_title) / 2;
+ if (x < 1)
+ x = 1;
+
+ gotoxy(x, 1);
+ textcolor(WHITE);
+ cprintf(mut_title);
+ textcolor(LIGHTGREY);
+ gotoxy(1,3);
+ j = 1;
+ }
+
+ /* mutation is actually a demonic power */
+ if (you.demon_pow[i] != 0)
+ textcolor(RED);
+
+ /* same as above, but power is enhanced by mutation */
+ if (you.demon_pow[i] != 0 && you.demon_pow[i] < you.mutation[i])
+ textcolor(LIGHTRED);
+
+ cprintf( mutation_name( i ) );
+ cprintf(EOL);
+ }
+ }
+
+ if (j == 0)
+ cprintf( "You are not a mutant." EOL );
+
+ if (getch() == 0)
+ getch();
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+
+ //cprintf("xxxxxxxxxxxxx");
+ //last_requested = 0;
+
+ return;
+} // end display_mutations()
+
+bool mutate(int which_mutation, bool failMsg)
+{
+ char mutat = which_mutation;
+ bool force_mutation = false; // is mutation forced?
+ int i;
+
+ if (which_mutation >= 1000) // must give mutation without failure
+ {
+ force_mutation = true;
+ mutat -= 1000;
+ which_mutation -= 1000;
+ }
+
+ // Undead bodies don't mutate, they fall apart. -- bwr
+ if (you.is_undead)
+ {
+ if (force_mutation
+ || (wearing_amulet(AMU_RESIST_MUTATION) && coinflip()))
+ {
+ mpr( "Your body decomposes!" );
+
+ if (coinflip())
+ lose_stat( STAT_RANDOM, 1 );
+ else
+ {
+ ouch( 3, 0, KILLED_BY_ROTTING );
+ rot_hp( roll_dice( 1, 3 ) );
+ }
+
+ return (true);
+ }
+
+ if (failMsg)
+ mpr("You feel odd for a moment.");
+
+ return (false);
+ }
+
+ if (wearing_amulet(AMU_RESIST_MUTATION)
+ && !force_mutation && !one_chance_in(10))
+ {
+ if (failMsg)
+ mpr("You feel odd for a moment.");
+
+ return (false);
+ }
+
+ if (you.mutation[MUT_MUTATION_RESISTANCE]
+ && !force_mutation
+ && (you.mutation[MUT_MUTATION_RESISTANCE] == 3 || !one_chance_in(3)))
+ {
+ if (failMsg)
+ mpr("You feel odd for a moment.");
+
+ return (false);
+ }
+
+ if (which_mutation == 100 && random2(15) < how_mutated())
+ {
+ if (!force_mutation && !one_chance_in(3))
+ return (false);
+ else
+ return (delete_mutation(100));
+ }
+
+ if (which_mutation == 100)
+ {
+ do
+ {
+ mutat = random2(NUM_MUTATIONS);
+
+ if (one_chance_in(1000))
+ return false;
+ }
+ while ((you.mutation[mutat] >= 3
+ && (mutat != MUT_STRONG && mutat != MUT_CLEVER
+ && mutat != MUT_AGILE) && (mutat != MUT_WEAK
+ && mutat != MUT_DOPEY
+ && mutat != MUT_CLUMSY))
+ || you.mutation[mutat] > 13
+ || random2(10) >= mutation_rarity[mutat] + you.demon_pow[mutat]);
+ }
+
+ if (you.mutation[mutat] >= 3
+ && (mutat != MUT_STRONG && mutat != MUT_CLEVER && mutat != MUT_AGILE)
+ && (mutat != MUT_WEAK && mutat != MUT_DOPEY && mutat != MUT_CLUMSY))
+ {
+ return false;
+ }
+
+ if (you.mutation[mutat] > 13 && !force_mutation)
+ return false;
+
+ // These can be forced by demonspawn
+ if ((mutat == MUT_TOUGH_SKIN
+ || (mutat >= MUT_GREEN_SCALES && mutat <= MUT_BONEY_PLATES)
+ || (mutat >= MUT_RED_SCALES && mutat <= MUT_PATTERNED_SCALES))
+ && body_covered() >= 3 && !force_mutation)
+ {
+ return false;
+ }
+
+ if (mutat == MUT_HORNS && you.species == SP_MINOTAUR)
+ return false;
+
+ // nagas have see invis and res poison and can spit poison
+ if (you.species == SP_NAGA)
+ {
+ if (mutat == MUT_ACUTE_VISION || mutat == MUT_POISON_RESISTANCE)
+ return false;
+
+ // gdl: spit poison 'upgrades' to breathe poison. Why not..
+ if (mutat == MUT_SPIT_POISON)
+ {
+ if (coinflip())
+ return false;
+ {
+ mutat = MUT_BREATHE_POISON;
+
+ // breathe poison replaces spit poison (so it takes the slot)
+ for (i = 0; i < 52; i++)
+ {
+ if (you.ability_letter_table[i] == ABIL_SPIT_POISON)
+ you.ability_letter_table[i] = ABIL_BREATHE_POISON;
+ }
+ }
+ }
+ }
+
+ // gnomes can already sense surroundings
+ if (you.species == SP_GNOME && mutat == MUT_MAPPING)
+ return false;
+
+ // spriggans already run at max speed (centaurs can get a bit faster)
+ if (you.species == SP_SPRIGGAN && mutat == MUT_FAST)
+ return false;
+
+ // this might have issues if we allowed it -- bwr
+ if (you.species == SP_KOBOLD
+ && (mutat == MUT_CARNIVOROUS || mutat == MUT_HERBIVOROUS))
+ {
+ return (false);
+ }
+
+ // This one can be forced by demonspawn
+ if (mutat == MUT_REGENERATION
+ && you.mutation[MUT_SLOW_METABOLISM] > 0 && !force_mutation)
+ {
+ return false; /* if you have a slow metabolism, no regen */
+ }
+
+ if (mutat == MUT_SLOW_METABOLISM && you.mutation[MUT_REGENERATION] > 0)
+ return false; /* if you have a slow metabolism, no regen */
+
+ // This one can be forced by demonspawn
+ if (mutat == MUT_ACUTE_VISION
+ && you.mutation[MUT_BLURRY_VISION] > 0 && !force_mutation)
+ {
+ return false;
+ }
+
+ if (mutat == MUT_BLURRY_VISION && you.mutation[MUT_ACUTE_VISION] > 0)
+ return false; /* blurred vision/see invis */
+
+ //jmf: added some checks for new mutations
+ if (mutat == MUT_STINGER
+ && !(you.species == SP_NAGA || player_genus(GENPC_DRACONIAN)))
+ {
+ return false;
+ }
+
+ // putting boots on after they are forced off. -- bwr
+ if (mutat == MUT_HOOVES
+ && (you.species == SP_NAGA || you.species == SP_CENTAUR
+ || you.species == SP_KENKU || player_genus(GENPC_DRACONIAN)))
+ {
+ return false;
+ }
+
+ if (mutat == MUT_BIG_WINGS && !player_genus(GENPC_DRACONIAN))
+ return false;
+
+ //jmf: added some checks for new mutations
+ mpr("You mutate.", MSGCH_MUTATION);
+
+ // find where these things are actually changed
+ // -- do not globally force redraw {dlb}
+ you.redraw_hit_points = 1;
+ you.redraw_magic_points = 1;
+ you.redraw_armour_class = 1;
+ you.redraw_evasion = 1;
+ you.redraw_experience = 1;
+ you.redraw_gold = 1;
+ //you.redraw_hunger = 1;
+
+ switch (mutat)
+ {
+ case MUT_STRONG:
+ if (you.mutation[MUT_WEAK] > 0)
+ {
+ delete_mutation(MUT_WEAK);
+ return true;
+ }
+ // replaces earlier, redundant code - 12mar2000 {dlb}
+ modify_stat(STAT_STRENGTH, 1, false);
+ break;
+
+ case MUT_CLEVER:
+ if (you.mutation[MUT_DOPEY] > 0)
+ {
+ delete_mutation(MUT_DOPEY);
+ return true;
+ }
+ // replaces earlier, redundant code - 12mar2000 {dlb}
+ modify_stat(STAT_INTELLIGENCE, 1, false);
+ break;
+
+ case MUT_AGILE:
+ if (you.mutation[MUT_CLUMSY] > 0)
+ {
+ delete_mutation(MUT_CLUMSY);
+ return true;
+ }
+ // replaces earlier, redundant code - 12mar2000 {dlb}
+ modify_stat(STAT_DEXTERITY, 1, false);
+ break;
+
+ case MUT_WEAK:
+ if (you.mutation[MUT_STRONG] > 0)
+ {
+ delete_mutation(MUT_STRONG);
+ return true;
+ }
+ modify_stat(STAT_STRENGTH, -1, true);
+ mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_DOPEY:
+ if (you.mutation[MUT_CLEVER] > 0)
+ {
+ delete_mutation(MUT_CLEVER);
+ return true;
+ }
+ modify_stat(STAT_INTELLIGENCE, -1, true);
+ mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_CLUMSY:
+ if (you.mutation[MUT_AGILE] > 0)
+ {
+ delete_mutation(MUT_AGILE);
+ return true;
+ }
+ modify_stat(STAT_DEXTERITY, -1, true);
+ mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_REGENERATION:
+ if (you.mutation[MUT_SLOW_METABOLISM] > 0)
+ {
+ // Should only get here from demonspawn, where our innate
+ // ability will clear away the counter-mutation.
+ while (delete_mutation(MUT_SLOW_METABOLISM))
+ ;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_ACUTE_VISION:
+ if (you.mutation[MUT_BLURRY_VISION] > 0)
+ {
+ // Should only get here from demonspawn, where our inate
+ // ability will clear away the counter-mutation.
+ while (delete_mutation(MUT_BLURRY_VISION))
+ ;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_CARNIVOROUS:
+ if (you.mutation[MUT_HERBIVOROUS] > 0)
+ {
+ delete_mutation(MUT_HERBIVOROUS);
+ return true;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_HERBIVOROUS:
+ if (you.mutation[MUT_CARNIVOROUS] > 0)
+ {
+ delete_mutation(MUT_CARNIVOROUS);
+ return true;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_SHOCK_RESISTANCE:
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_FAST_METABOLISM:
+ if (you.mutation[MUT_SLOW_METABOLISM] > 0)
+ {
+ delete_mutation(MUT_SLOW_METABOLISM);
+ return true;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_SLOW_METABOLISM:
+ if (you.mutation[MUT_FAST_METABOLISM] > 0)
+ {
+ delete_mutation(MUT_FAST_METABOLISM);
+ return true;
+ }
+ //if (you.mutation[mutat] == 0 || you.mutation[mutat] == 2)
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_TELEPORT_CONTROL:
+ you.attribute[ATTR_CONTROL_TELEPORT]++;
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+
+ case MUT_HOOVES: //jmf: like horns
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ if (you.equip[EQ_BOOTS] != -1)
+ {
+ FixedVector < char, 8 > removed;
+
+ for (int i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
+ {
+ removed[i] = 0;
+ }
+
+ removed[EQ_BOOTS] = 1;
+ remove_equipment(removed);
+ }
+ break;
+
+ case MUT_CLAWS:
+ mpr( gain_mutation[ mutat ][ you.mutation[mutat] ], MSGCH_MUTATION );
+
+ // gloves aren't prevented until level three
+ if (you.mutation[ mutat ] >= 3 && you.equip[ EQ_GLOVES ] != -1)
+ {
+ FixedVector < char, 8 > removed;
+
+ for (int i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
+ {
+ removed[i] = 0;
+ }
+
+ removed[ EQ_GLOVES ] = 1;
+ remove_equipment( removed );
+ }
+ break;
+
+ case MUT_HORNS: // horns force your helmet off
+ {
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+
+ if (you.equip[EQ_HELMET] != -1
+ && you.inv[you.equip[EQ_HELMET]].plus2 > 1)
+ {
+ break; // horns don't push caps/wizard hats off
+ }
+
+ FixedVector < char, 8 > removed;
+
+ for (int i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
+ {
+ removed[i] = 0;
+ }
+
+ removed[EQ_HELMET] = 1;
+ remove_equipment(removed);
+ }
+ break;
+
+ case MUT_STRONG_STIFF:
+ if (you.mutation[MUT_FLEXIBLE_WEAK] > 0)
+ {
+ delete_mutation(MUT_FLEXIBLE_WEAK);
+ return true;
+ }
+ modify_stat(STAT_STRENGTH, 1, true);
+ modify_stat(STAT_DEXTERITY, -1, true);
+ mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_FLEXIBLE_WEAK:
+ if (you.mutation[MUT_STRONG_STIFF] > 0)
+ {
+ delete_mutation(MUT_STRONG_STIFF);
+ return true;
+ }
+ modify_stat(STAT_STRENGTH, -1, true);
+ modify_stat(STAT_DEXTERITY, 1, true);
+ mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_FRAIL:
+ if (you.mutation[MUT_ROBUST] > 0)
+ {
+ delete_mutation(MUT_ROBUST);
+ return true;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ you.mutation[mutat]++;
+ calc_hp();
+ return true;
+
+ case MUT_ROBUST:
+ if (you.mutation[MUT_FRAIL] > 0)
+ {
+ delete_mutation(MUT_FRAIL);
+ return true;
+ }
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ you.mutation[mutat]++;
+ calc_hp();
+ return true;
+
+ case MUT_BLACK_SCALES:
+ case MUT_BONEY_PLATES:
+ modify_stat(STAT_DEXTERITY, -1, true);
+ // deliberate fall-through
+ default:
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_GREY2_SCALES:
+ if (you.mutation[mutat] != 1)
+ modify_stat(STAT_DEXTERITY, -1, true);
+
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_METALLIC_SCALES:
+ if (you.mutation[mutat] == 0)
+ modify_stat(STAT_DEXTERITY, -2, true);
+ else
+ modify_stat(STAT_DEXTERITY, -1, true);
+
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+
+ case MUT_RED2_SCALES:
+ case MUT_YELLOW_SCALES:
+ if (you.mutation[mutat] != 0)
+ modify_stat(STAT_DEXTERITY, -1, true);
+
+ mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
+ break;
+ }
+
+ you.mutation[mutat]++;
+
+ /* remember, some mutations don't get this far (eg frail) */
+ return true;
+} // end mutation()
+
+int how_mutated(void)
+{
+ int j = 0;
+
+ for (int i = 0; i < 100; i++)
+ {
+ if (you.mutation[i] && you.demon_pow[i] < you.mutation[i])
+ {
+ // these allow for 14 levels:
+ if (i == MUT_STRONG || i == MUT_CLEVER || i == MUT_AGILE
+ || i == MUT_WEAK || i == MUT_DOPEY || i == MUT_CLUMSY)
+ {
+ j += (you.mutation[i] / 5 + 1);
+ }
+ else
+ {
+ j += you.mutation[i];
+ }
+ }
+ }
+
+#if DEBUG_DIAGNOSTICS
+ snprintf( info, INFO_SIZE, "levels: %d", j );
+ mpr( info, MSGCH_DIAGNOSTICS );
+#endif
+
+ return (j);
+} // end how_mutated()
+
+bool delete_mutation(char which_mutation)
+{
+ char mutat = which_mutation;
+ int i;
+
+ if (you.mutation[MUT_MUTATION_RESISTANCE] > 1
+ && (you.mutation[MUT_MUTATION_RESISTANCE] == 3 || coinflip()))
+ {
+ mpr("You feel rather odd for a moment.");
+ return false;
+ }
+
+ if (which_mutation == 100)
+ {
+ do
+ {
+ mutat = random2(NUM_MUTATIONS);
+ if (one_chance_in(1000))
+ return false;
+ }
+ while ((you.mutation[mutat] == 0
+ && (mutat != MUT_STRONG && mutat != MUT_CLEVER && mutat != MUT_AGILE)
+ && (mutat != MUT_WEAK && mutat != MUT_DOPEY && mutat != MUT_CLUMSY))
+ || random2(10) >= mutation_rarity[mutat]
+ || you.demon_pow[mutat] >= you.mutation[mutat]);
+ }
+
+ if (you.mutation[mutat] == 0)
+ return false;
+
+ if (you.demon_pow[mutat] >= you.mutation[mutat])
+ return false;
+
+ mpr("You mutate.", MSGCH_MUTATION);
+
+ switch (mutat)
+ {
+ case MUT_STRONG:
+ modify_stat(STAT_STRENGTH, -1, true);
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_CLEVER:
+ modify_stat(STAT_INTELLIGENCE, -1, true);
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_AGILE:
+ modify_stat(STAT_DEXTERITY, -1, true);
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_WEAK:
+ modify_stat(STAT_STRENGTH, 1, false);
+ break;
+
+ case MUT_DOPEY:
+ modify_stat(STAT_INTELLIGENCE, 1, false);
+ break;
+
+ case MUT_CLUMSY:
+ // replaces earlier, redundant code - 12mar2000 {dlb}
+ modify_stat(STAT_DEXTERITY, 1, false);
+ break;
+
+ case MUT_SHOCK_RESISTANCE:
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_FAST_METABOLISM:
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_SLOW_METABOLISM:
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_TELEPORT_CONTROL:
+ you.attribute[ATTR_CONTROL_TELEPORT]--;
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_STRONG_STIFF:
+ modify_stat(STAT_STRENGTH, -1, true);
+ modify_stat(STAT_DEXTERITY, 1, true);
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_FLEXIBLE_WEAK:
+ modify_stat(STAT_STRENGTH, 1, true);
+ modify_stat(STAT_DEXTERITY, -1, true);
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ break;
+
+ case MUT_FRAIL:
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ if (you.mutation[mutat] > 0)
+ you.mutation[mutat]--;
+ calc_hp();
+ return true;
+
+ case MUT_ROBUST:
+ mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
+ if (you.mutation[mutat] > 0)
+ you.mutation[mutat]--;
+ calc_hp();
+ return true;
+
+ case MUT_BLACK_SCALES:
+ case MUT_BONEY_PLATES:
+ modify_stat(STAT_DEXTERITY, 1, true);
+
+ default:
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_GREY2_SCALES:
+ if (you.mutation[mutat] != 2)
+ modify_stat(STAT_DEXTERITY, 1, true);
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_METALLIC_SCALES:
+ if (you.mutation[mutat] == 1)
+ modify_stat(STAT_DEXTERITY, 2, true);
+ else
+ modify_stat(STAT_DEXTERITY, 1, true);
+
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_RED2_SCALES:
+ case MUT_YELLOW_SCALES:
+ if (you.mutation[mutat] != 1)
+ modify_stat(STAT_DEXTERITY, 1, true);
+
+ mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
+ break;
+
+ case MUT_BREATHE_POISON:
+ // can't be removed yet, but still covered:
+ if (you.species == SP_NAGA)
+ {
+ // natural ability to spit poison retakes the slot
+ for (i = 0; i < 52; i++)
+ {
+ if (you.ability_letter_table[i] == ABIL_BREATHE_POISON)
+ you.ability_letter_table[i] = ABIL_SPIT_POISON;
+ }
+ }
+ break;
+ }
+
+ // find where these things are actually altered
+ /// -- do not globally force redraw {dlb}
+ you.redraw_hit_points = 1;
+ you.redraw_magic_points = 1;
+ you.redraw_armour_class = 1;
+ you.redraw_evasion = 1;
+ you.redraw_experience = 1;
+ you.redraw_gold = 1;
+ //you.redraw_hunger = 1;
+
+ if (you.mutation[mutat] > 0)
+ you.mutation[mutat]--;
+
+ return true;
+} // end delete_mutation()
+
+char body_covered(void)
+{
+ /* checks how much of your body is covered by scales etc */
+ char covered = 0;
+
+ if (you.species == SP_NAGA)
+ covered++;
+
+ if (player_genus(GENPC_DRACONIAN))
+ return 3;
+
+ covered += you.mutation[MUT_TOUGH_SKIN];
+ covered += you.mutation[MUT_GREEN_SCALES];
+ covered += you.mutation[MUT_BLACK_SCALES];
+ covered += you.mutation[MUT_GREY_SCALES];
+ covered += you.mutation[MUT_BONEY_PLATES];
+ covered += you.mutation[MUT_RED_SCALES];
+ covered += you.mutation[MUT_NACREOUS_SCALES];
+ covered += you.mutation[MUT_GREY2_SCALES];
+ covered += you.mutation[MUT_METALLIC_SCALES];
+ covered += you.mutation[MUT_BLACK2_SCALES];
+ covered += you.mutation[MUT_WHITE_SCALES];
+ covered += you.mutation[MUT_YELLOW_SCALES];
+ covered += you.mutation[MUT_BROWN_SCALES];
+ covered += you.mutation[MUT_BLUE_SCALES];
+ covered += you.mutation[MUT_PURPLE_SCALES];
+ covered += you.mutation[MUT_SPECKLED_SCALES];
+ covered += you.mutation[MUT_ORANGE_SCALES];
+ covered += you.mutation[MUT_INDIGO_SCALES];
+ covered += you.mutation[MUT_RED2_SCALES];
+ covered += you.mutation[MUT_IRIDESCENT_SCALES];
+ covered += you.mutation[MUT_PATTERNED_SCALES];
+
+ return covered;
+}
+
+const char *mutation_name( char which_mutat, int level )
+{
+ static char mut_string[INFO_SIZE];
+
+ // level == -1 means default action of current level
+ if (level == -1)
+ level = you.mutation[ which_mutat ];
+
+ if (which_mutat == MUT_STRONG || which_mutat == MUT_CLEVER
+ || which_mutat == MUT_AGILE || which_mutat == MUT_WEAK
+ || which_mutat == MUT_DOPEY || which_mutat == MUT_CLUMSY)
+ {
+ snprintf( mut_string, sizeof( mut_string ), "%s%d).",
+ mutation_descrip[ which_mutat ][0], level );
+
+ return (mut_string);
+ }
+
+ // Some mutations only have one "level", and it's better
+ // to show the first level description than a blank description.
+ if (mutation_descrip[ which_mutat ][ level - 1 ][0] == '\0')
+ return (mutation_descrip[ which_mutat ][ 0 ]);
+ else
+ return (mutation_descrip[ which_mutat ][ level - 1 ]);
+} // end mutation_name()
+
+/* Use an attribute counter for how many demonic mutations a dspawn has */
+void demonspawn(void)
+{
+ int whichm = -1;
+ char howm = 1;
+ int counter = 0;
+
+ const int scale_levels = body_covered();
+
+ you.attribute[ATTR_NUM_DEMONIC_POWERS]++;
+
+ mpr("Your demonic ancestry asserts itself...", MSGCH_INTRINSIC_GAIN);
+
+ // Merged the demonspawn lists into a single loop. Now a high level
+ // character can potentially get mutations from the low level list if
+ // its having trouble with the high level list.
+ do
+ {
+ if (you.experience_level >= 10)
+ {
+ if (you.skills[SK_CONJURATIONS] < 5)
+ { // good conjurers don't get bolt of draining
+ whichm = MUT_SMITE;
+ howm = 1;
+ }
+
+ if (you.skills[SK_CONJURATIONS] < 10 && one_chance_in(4))
+ { // good conjurers don't get hellfire
+ whichm = MUT_HURL_HELLFIRE;
+ howm = 1;
+ }
+
+ if (you.skills[SK_SUMMONINGS] < 5 && one_chance_in(3))
+ { // good summoners don't get summon demon
+ whichm = MUT_SUMMON_DEMONS;
+ howm = 1;
+ }
+
+ if (one_chance_in(8))
+ {
+ whichm = MUT_MAGIC_RESISTANCE;
+ howm = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in(12))
+ {
+ whichm = MUT_FAST;
+ howm = 1;
+ }
+
+ if (one_chance_in(7))
+ {
+ whichm = MUT_TELEPORT_AT_WILL;
+ howm = 2;
+ }
+
+ if (one_chance_in(10))
+ {
+ whichm = MUT_REGENERATION;
+ howm = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in(12))
+ {
+ whichm = MUT_SHOCK_RESISTANCE;
+ howm = 1;
+ }
+
+ if (!you.mutation[MUT_CALL_TORMENT] && one_chance_in(15))
+ {
+ whichm = MUT_TORMENT_RESISTANCE;
+ howm = 1;
+ }
+
+ if (one_chance_in(12))
+ {
+ whichm = MUT_NEGATIVE_ENERGY_RESISTANCE;
+ howm = 1 + random2(3);
+ }
+
+ if (!you.mutation[MUT_TORMENT_RESISTANCE] && one_chance_in(20))
+ {
+ whichm = MUT_CALL_TORMENT;
+ howm = 1;
+ }
+
+ if (you.skills[SK_SUMMONINGS] < 5 && you.skills[SK_NECROMANCY] < 5
+ && one_chance_in(12))
+ {
+ whichm = MUT_CONTROL_DEMONS;
+ howm = 1;
+ }
+
+ if (you.skills[SK_TRANSLOCATIONS] < 5 && one_chance_in(15))
+ {
+ whichm = MUT_PANDEMONIUM;
+ howm = 1;
+ }
+
+ if (you.religion != GOD_VEHUMET && one_chance_in(11))
+ {
+ whichm = MUT_DEATH_STRENGTH;
+ howm = 1;
+ }
+
+ if (you.religion != GOD_VEHUMET && one_chance_in(11))
+ {
+ whichm = MUT_CHANNEL_HELL;
+ howm = 1;
+ }
+
+ if (you.skills[SK_SUMMONINGS] < 3 && you.skills[SK_NECROMANCY] < 3
+ && one_chance_in(10))
+ {
+ whichm = MUT_RAISE_DEAD;
+ howm = 1;
+ }
+
+ if (you.skills[SK_UNARMED_COMBAT] > 5 && one_chance_in(14))
+ {
+ whichm = MUT_DRAIN_LIFE;
+ howm = 1;
+ }
+ }
+
+ // check here so we can see if we need to extent our options:
+ if (whichm != -1 && you.mutation[whichm] != 0)
+ whichm = -1;
+
+ if (you.experience_level < 10 || (counter > 0 && whichm == -1))
+ {
+ 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))
+ && (!you.skills[SK_ICE_MAGIC] // already ice & fire?
+ || !you.skills[SK_FIRE_MAGIC]))
+ {
+ // try to give the flavour the character doesn't have:
+ if (!you.skills[SK_FIRE_MAGIC])
+ whichm = MUT_THROW_FLAMES;
+ else if (!you.skills[SK_ICE_MAGIC])
+ whichm = MUT_THROW_FROST;
+ else
+ whichm = (coinflip() ? MUT_THROW_FLAMES : MUT_THROW_FROST);
+
+ howm = 1;
+ }
+
+ if (!you.skills[SK_SUMMONINGS] && one_chance_in(3))
+ { /* summoners don't get summon imp */
+ whichm = (you.experience_level < 10) ? MUT_SUMMON_MINOR_DEMONS
+ : MUT_SUMMON_DEMONS;
+ howm = 1;
+ }
+
+ if (one_chance_in(4))
+ {
+ whichm = MUT_POISON_RESISTANCE;
+ howm = 1;
+ }
+
+ if (one_chance_in(4))
+ {
+ whichm = MUT_COLD_RESISTANCE;
+ howm = 1;
+ }
+
+ if (one_chance_in(4))
+ {
+ whichm = MUT_HEAT_RESISTANCE;
+ howm = 1;
+ }
+
+ if (one_chance_in(5))
+ {
+ whichm = MUT_ACUTE_VISION;
+ howm = 1;
+ }
+
+ if (!you.skills[SK_POISON_MAGIC] && one_chance_in(7))
+ {
+ whichm = MUT_SPIT_POISON;
+ howm = (you.experience_level < 10) ? 1 : 3;
+ }
+
+ if (one_chance_in(10))
+ {
+ whichm = MUT_MAPPING;
+ howm = 3;
+ }
+
+ if (one_chance_in(12))
+ {
+ whichm = MUT_TELEPORT_CONTROL;
+ howm = 1;
+ }
+
+ 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
+ && one_chance_in(5))
+ {
+ whichm = MUT_BREATHE_FLAMES;
+ howm = 2;
+ }
+
+ if (!you.skills[SK_TRANSLOCATIONS] && one_chance_in(12))
+ {
+ whichm = (you.experience_level < 10) ? MUT_BLINK
+ : MUT_TELEPORT_AT_WILL;
+ howm = 2;
+ }
+
+ if (scale_levels < 3 && one_chance_in( 1 + scale_levels * 5 ))
+ {
+ const int bonus = (you.experience_level < 10) ? 0 : 1;
+ int levels = 0;
+
+ if (one_chance_in(10))
+ {
+ whichm = MUT_TOUGH_SKIN;
+ levels = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in(24))
+ {
+ whichm = MUT_GREEN_SCALES;
+ levels = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in(24))
+ {
+ whichm = MUT_BLACK_SCALES;
+ levels = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in(24))
+ {
+ whichm = MUT_GREY_SCALES;
+ levels = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in(12))
+ {
+ whichm = MUT_RED_SCALES + random2(16);
+
+ switch (whichm)
+ {
+ case MUT_RED_SCALES:
+ case MUT_NACREOUS_SCALES:
+ case MUT_BLACK2_SCALES:
+ case MUT_WHITE_SCALES:
+ case MUT_BLUE_SCALES:
+ case MUT_SPECKLED_SCALES:
+ case MUT_ORANGE_SCALES:
+ case MUT_IRIDESCENT_SCALES:
+ case MUT_PATTERNED_SCALES:
+ levels = (coinflip() ? 2 : 3);
+ break;
+
+ default:
+ levels = (coinflip() ? 1 : 2);
+ break;
+ }
+ }
+
+ if (one_chance_in(30))
+ {
+ whichm = MUT_BONEY_PLATES;
+ levels = (coinflip() ? 1 : 2);
+ }
+
+ if (levels)
+ howm = MINIMUM( 3 - scale_levels, levels + bonus );
+ }
+
+ if (one_chance_in(25))
+ {
+ whichm = MUT_REPULSION_FIELD;
+ howm = (coinflip() ? 2 : 3);
+ }
+
+ if (one_chance_in( (you.experience_level < 10) ? 5 : 20 ))
+ {
+ whichm = MUT_HORNS;
+ howm = (coinflip() ? 1 : 2);
+
+ if (you.experience_level > 4 || one_chance_in(5))
+ howm++;
+ }
+ }
+
+ if (whichm != -1 && you.mutation[whichm] != 0)
+ whichm = -1;
+
+ counter++;
+ }
+ while (whichm == -1 && counter < 5000);
+
+ if (whichm == -1 || !perma_mutate( whichm, howm ))
+ {
+ /* unlikely but remotely possible */
+ /* I know this is a cop-out */
+ modify_stat(STAT_STRENGTH, 1, true);
+ modify_stat(STAT_INTELLIGENCE, 1, true);
+ modify_stat(STAT_DEXTERITY, 1, true);
+ mpr("You feel much better now.", MSGCH_INTRINSIC_GAIN);
+ }
+} // end demonspawn()
+
+bool perma_mutate(int which_mut, char how_much)
+{
+ char levels = 0;
+
+ if (mutate(which_mut + 1000))
+ levels++;
+
+ if (how_much >= 2 && mutate(which_mut + 1000))
+ levels++;
+
+ if (how_much >= 3 && mutate(which_mut + 1000))
+ levels++;
+
+ you.demon_pow[which_mut] = levels;
+
+ return (levels > 0);
+} // end perma_mutate()
+
+bool give_good_mutation(bool failMsg)
+{
+ int temp_rand = 0; // probability determination {dlb}
+ int which_good_one = 0;
+
+ temp_rand = random2(25);
+
+ which_good_one = ((temp_rand >= 24) ? MUT_TOUGH_SKIN :
+ (temp_rand == 23) ? MUT_STRONG :
+ (temp_rand == 22) ? MUT_CLEVER :
+ (temp_rand == 21) ? MUT_AGILE :
+ (temp_rand == 20) ? MUT_HEAT_RESISTANCE :
+ (temp_rand == 19) ? MUT_COLD_RESISTANCE :
+ (temp_rand == 18) ? MUT_SHOCK_RESISTANCE :
+ (temp_rand == 17) ? MUT_REGENERATION :
+ (temp_rand == 16) ? MUT_TELEPORT_CONTROL :
+ (temp_rand == 15) ? MUT_MAGIC_RESISTANCE :
+ (temp_rand == 14) ? MUT_FAST :
+ (temp_rand == 13) ? MUT_ACUTE_VISION :
+ (temp_rand == 12) ? MUT_GREEN_SCALES :
+ (temp_rand == 11) ? MUT_BLACK_SCALES :
+ (temp_rand == 10) ? MUT_GREY_SCALES :
+ (temp_rand == 9) ? MUT_BONEY_PLATES :
+ (temp_rand == 8) ? MUT_REPULSION_FIELD :
+ (temp_rand == 7) ? MUT_POISON_RESISTANCE :
+ (temp_rand == 6) ? MUT_TELEPORT_AT_WILL :
+ (temp_rand == 5) ? MUT_SPIT_POISON :
+ (temp_rand == 4) ? MUT_MAPPING :
+ (temp_rand == 3) ? MUT_BREATHE_FLAMES :
+ (temp_rand == 2) ? MUT_BLINK :
+ (temp_rand == 1) ? MUT_CLARITY
+ : MUT_ROBUST);
+
+ return (mutate(which_good_one, failMsg));
+} // end give_good_mutation()
+
+bool give_bad_mutation(bool forceMutation, bool failMsg)
+{
+ int temp_rand = 0; // probability determination {dlb}
+ int which_bad_one = 0;
+
+ temp_rand = random2(12);
+
+ which_bad_one = ((temp_rand >= 11) ? MUT_CARNIVOROUS :
+ (temp_rand == 10) ? MUT_HERBIVOROUS :
+ (temp_rand == 9) ? MUT_FAST_METABOLISM :
+ (temp_rand == 8) ? MUT_WEAK :
+ (temp_rand == 7) ? MUT_DOPEY :
+ (temp_rand == 6) ? MUT_CLUMSY :
+ (temp_rand == 5) ? MUT_TELEPORT :
+ (temp_rand == 4) ? MUT_DEFORMED :
+ (temp_rand == 3) ? MUT_LOST :
+ (temp_rand == 2) ? MUT_DETERIORATION :
+ (temp_rand == 1) ? MUT_BLURRY_VISION
+ : MUT_FRAIL);
+
+ if (forceMutation)
+ which_bad_one += 1000;
+
+ return (mutate(which_bad_one), failMsg);
+} // end give_bad_mutation()
+
+//jmf: might be useful somewhere (eg Xom or transmigration effect)
+bool give_cosmetic_mutation()
+{
+ int mutation = -1;
+ int how_much = 0;
+ int counter = 0;
+
+ do
+ {
+ mutation = MUT_DEFORMED;
+ how_much = 1 + random2(3);
+
+ if (one_chance_in(6))
+ {
+ mutation = MUT_ROBUST;
+ how_much = 1 + random2(3);
+ }
+
+ if (one_chance_in(6))
+ {
+ mutation = MUT_FRAIL;
+ how_much = 1 + random2(3);
+ }
+
+ if (one_chance_in(5))
+ {
+ mutation = MUT_TOUGH_SKIN;
+ how_much = 1 + random2(3);
+ }
+
+ if (one_chance_in(4))
+ {
+ mutation = MUT_CLAWS;
+ how_much = 1 + random2(3);
+ }
+
+ if (you.species != SP_CENTAUR && you.species != SP_NAGA
+ && you.species != SP_KENKU && !player_genus(GENPC_DRACONIAN)
+ && one_chance_in(5))
+ {
+ mutation = MUT_HOOVES;
+ how_much = 1;
+ }
+
+ if (player_genus(GENPC_DRACONIAN) && one_chance_in(5))
+ {
+ mutation = MUT_BIG_WINGS;
+ how_much = 1;
+ }
+
+ if (one_chance_in(5))
+ {
+ mutation = MUT_CARNIVOROUS;
+ how_much = 1 + random2(3);
+ }
+
+ if (one_chance_in(6))
+ {
+ mutation = MUT_HORNS;
+ how_much = 1 + random2(3);
+ }
+
+ if ((you.species == SP_NAGA || player_genus(GENPC_DRACONIAN))
+ && one_chance_in(4))
+ {
+ mutation = MUT_STINGER;
+ how_much = 1 + random2(3);
+ }
+
+ if (you.species == SP_NAGA && one_chance_in(6))
+ {
+ mutation = MUT_BREATHE_POISON;
+ how_much = 1;
+ }
+
+ if (!(you.species == SP_NAGA || player_genus(GENPC_DRACONIAN))
+ && one_chance_in(7))
+ {
+ mutation = MUT_SPIT_POISON;
+ how_much = 1;
+ }
+
+ if (!(you.species == SP_NAGA || player_genus(GENPC_DRACONIAN))
+ && one_chance_in(8))
+ {
+ mutation = MUT_BREATHE_FLAMES;
+ how_much = 1 + random2(3);
+ }
+
+ if (you.mutation[mutation] > 0)
+ how_much -= you.mutation[mutation];
+
+ if (how_much < 0)
+ how_much = 0;
+ }
+ while (how_much == 0 && counter++ < 5000);
+
+ if (how_much != 0)
+ return mutate(mutation);
+ else
+ return false;
+} // end give_cosmetic_mutation()