Example #1
0
 public override bool FireEvent(Event E)
 {
     if (E.ID == "EndTurnEngulfing")
     {
         if (descriptionSet == false)
         {
             IPart.ThePlayer.GetPart <Description>().Short = "I'm not a bad slime";
             descriptionSet = true;
         }
         GameObject parameter = E.GetParameter <GameObject>("Object");
         if (parameter != null)
         {
             Damage damage = new Damage(Stat.Random(IPart.ThePlayer.Statistics["Toughness"].BaseValue / 2, IPart.ThePlayer.Statistics["Toughness"].BaseValue));
             Event  E1     = Event.New("TakeDamage", 0, 0, 0);
             E1.AddParameter("Damage", (object)damage);
             E1.AddParameter("Owner", (object)this.ParentObject);
             E1.AddParameter("Attacker", (object)this.ParentObject);
             E1.AddParameter("Message", this.DamageMessage);
             parameter.FireEvent(E1);
             if (parameter.hitpoints <= 0)
             {
                 if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&wAverage")
                 {
                     this.statGains(1);
                 }
                 else if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&WTough")
                 {
                     this.statGains(2);
                 }
                 else if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&rVery Tough")
                 {
                     this.statGains(4);
                 }
                 else if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&RImpossible")
                 {
                     this.statGains(8);
                 }
                 Mutations targetMutations = parameter.GetPart <Mutations>();
                 Mutations playerMutations = IPart.ThePlayer.GetPart <Mutations>();
                 if (targetMutations != null)
                 {
                     foreach (BaseMutation mutation in targetMutations.MutationList)
                     {
                         if (!playerMutations.HasMutation(mutation) && !excludedMutations.Contains(mutation.Name) && mutation.CompatibleWith(IPart.ThePlayer))
                         {
                             playerMutations.AddMutation(mutation, 1);
                         }
                     }
                 }
                 Stomach part = IPart.ThePlayer.GetPart <Stomach>();
                 IPart.ThePlayer.RemoveEffect("Famished", false);
                 part.HungerLevel    = 0;
                 part.CookCount      = 0;
                 part.CookingCounter = 0;
                 part.Water          = 30000;
             }
         }
     }
     return(true);
 }
        private static void ApplyMutations(CharacterTemplate buildTemplate, List <MLNode> mutationNodes)
        {
            if (!buildTemplate.genotypeEntry.IsMutant)
            {
                return;
            }
            Mutations part = buildTemplate.PlayerBody.GetPart <Mutations>();

            foreach (MLNode node in mutationNodes)
            {
                if (node.Entry != null && node.Selected > 0)
                {
                    if (node.Entry.Mutation != null)
                    {
                        BaseMutation baseMutation = node.Entry.CreateInstance();
                        baseMutation.SetVariant(node.Variant);
                        part.AddMutation(baseMutation, node.Selected);
                    }
                    else if (node.Entry.DisplayName == "Chimera")
                    {
                        buildTemplate.MutationLevel = "Chimera";
                    }
                    else if (node.Entry.DisplayName == "Esper")
                    {
                        buildTemplate.MutationLevel = "Esper";
                    }
                }
            }
        }
Example #3
0
        public void domutate()
        {
            if (ParentObject.IsPlayer() || ParentObject.IsMemberOfFaction("Templar"))
            {
                return;
            }
            int roll = Stat.Random(1, 100);

            Log("Titroll:" + roll.ToString() + "/" + Chance.ToString());
            if (roll <= Chance)
            {
                Mutations mutations = ParentObject.GetPart("Mutations") as Mutations;
                if (mutations == null)
                {
                    Log("Can mutate, no mutations part");
                    return;
                }
                if (!MutationFactory.MutationsByName.ContainsKey(Mutation))
                {
                    Log("Mutation " + Mutation + " isn't recognised");
                }
                mutations.AddMutation(MutationFactory.MutationsByName[Mutation].CreateInstance(), Level);
                Log("mutated");
            }
        }
        public override bool Mutate(GameObject GO, int Level)
        {
            this.Unmutate(GO);
            Mutations GainPSiFocus = GO.GetPart <Mutations>();

            if (!GainPSiFocus.HasMutation("FocusPsi"))
            {
                GainPSiFocus.AddMutation("FocusPsi", 1);
                //AddPlayerMessage("Has Focus Psi.");
            }
            this.ActivateThermokinesisAbilityID = base.AddMyActivatedAbility("Alter Temperatures", "CommandAlterTemperatures", "Mental Mutation", null, "*", null, false, false, false, false, false);
            this.ChangeLevel(Level);
            return(base.Mutate(GO, Level));
        }
        public override bool Mutate(GameObject GO, int Level)
        {
            // string PsychomateriartisinfoSource = "{ \"Psychomateriartis\": [\"*cult*, mind-smiths\", \"Forgemasters *cult*\"] }";
            // SimpleJSON.JSONNode PsychomateriartisInfo = SimpleJSON.JSON.Parse(PsychomateriartisinfoSource);

            // WMExtendedMutations.History.AddToHistorySpice("spice.extradimensional", PsychomateriartisInfo["Psychomateriartis"]);

            Mutations GainPSiFocus = GO.GetPart <Mutations>();

            if (!GainPSiFocus.HasMutation("FocusPsi"))
            {
                GainPSiFocus.AddMutation("FocusPsi", 1);
            }

            this.ManifestPsiWeaponActivatedAbilityID = base.AddMyActivatedAbility("Psi-Forge", "ManifestWeaponCommand", "Mental Mutation", "Manifest or dismiss a psionic weapon.\n\n");
            this.ReturnPsiWeaponActivatedAbilityID   = base.AddMyActivatedAbility("Return Psi-Weapon", "ReturnWeaponCommand", "Mental Mutation", "Rematerialize your last previously crafted psi-arm to your hand so long as you are in the same parasang, this is a turnless action.", "\u03A9");

            return(base.Mutate(GO, Level));
        }
Example #6
0
        public override bool Mutate(GameObject GO, int Level)
        {
            // string PsybrachiomancyinfoSource = "{ \"Psybrachiomancy\": [\"*cult*, the Asuran\", \"Many-Armed *cult*\"] }";
            // SimpleJSON.JSONNode PsybrachiomancyInfo = SimpleJSON.JSON.Parse(PsybrachiomancyinfoSource);

            // WMExtendedMutations.History.AddToHistorySpice("spice.extradimensional", PsybrachiomancyInfo["Psybrachiomancy"]);

            Mutations GainPSiFocus = GO.GetPart <Mutations>();

            if (!GainPSiFocus.HasMutation("FocusPsi"))
            {
                GainPSiFocus.AddMutation("FocusPsi", 1);
            }
            this.ActivatedAbilityID = base.AddMyActivatedAbility("Manifest Limb", "CommandManifestLimb", "Mental Mutation", "Manifest a psychic arm.\n\n Instead of using strength for penetration, a weapon’s penetration when wielded with a psionic arm is limited to your Ego modifier and the weapons’ penetration value.\n\n"
                                                                 + "(Dismembered psionic arms may not dissapate and may require re-weaving to repair, no damage is taken from blows that sever psionic limbs.)\n"
                                                                 + "If the set of arms you summon are more than your Willpower Modifier, you will be given the 'psi-exhaustion' effect temporarily.", ">", null, false, false, false, false, false, false, false, 10, null);
            this.ActivatedAbilityID = base.AddMyActivatedAbility("Dismiss Limb", "CommandDismissLimb", "Mental Mutation", "Dismiss a psychic arm.\n\n", "<", null, false, false, false, false, false, false, false, 10, null);
            this.ChangeLevel(Level);
            return(base.Mutate(GO, Level));
        }
Example #7
0
        public override bool Mutate(GameObject GO, int Level)
        {
            Mutations GainPSiFocus = GO.GetPart <Mutations>();

            if (!GainPSiFocus.HasMutation("FocusPsi"))
            {
                GainPSiFocus.AddMutation("FocusPsi", 1);
            }
            if (!ParentObject.HasPart("ShimmeringShroudHandler"))
            {
                ParentObject.AddPart <ShimmeringShroudHandler>();
            }
            ActivateShimmeringShroudAbilityID = base.AddMyActivatedAbility("Activate Shroud", "CommandShimmeringShroud", "Mental Mutation", null, "*", null, false, false, false, false, false);
            ChargePotentialAbilityID          = base.AddMyActivatedAbility("Charge Potential", "CommandChargePotencyShroud", "Mental Mutation", null, "*", null, true, false, true, false, false);
            PotencyForChargesAbility          = base.AddMyActivatedAbility("Recharge Battery", "ChargeBatteryEvent", "Electrokinesis", null, "~", null, false, false, true, false, false);
            ElectrokinesisGauge = base.AddMyActivatedAbility("Electrokinesis", "ElectroToggleEvent", "Mutation");

            this.ChangeLevel(Level);
            return(base.Mutate(GO, Level));
        }
        public override bool Mutate(GameObject GO, int Level)
        {
            // string CombustionBlastinfoSource = "{ \"CombustionBlast\": [\"*cult*, the Fire-Eyed\", \"mind-blast *cult*\"] }";
            // SimpleJSON.JSONNode CombustionInfo = SimpleJSON.JSON.Parse(CombustionBlastinfoSource);

            // WMExtendedMutations.History.AddToHistorySpice("spice.extradimensional", CombustionInfo["CombustionBlast"]);

            this.Unmutate(GO);
            Mutations GainPSiFocus = GO.GetPart <Mutations>();

            if (!GainPSiFocus.HasMutation("FocusPsi"))
            {
                GainPSiFocus.AddMutation("FocusPsi", 1);
                //AddPlayerMessage("Has Focus Psi.");
            }
            this.CombustionBlastActivatedAbilityID       = base.AddMyActivatedAbility("fire volley", "CommandCombustionBlast", "Mental Mutation", null, "*", null, false, false, false, false, false);
            this.CombustionBlastVolleyActivatedAbilityID = base.AddMyActivatedAbility("quick fire", "CommandQuickFire", "Mental Mutation", null, "*", null, false, false, false, false, false);
            this.ChangeLevel(Level);
            return(base.Mutate(GO, Level));
        }
Example #9
0
 public void EvolveSludge()
 {
     if (this.newLiquid != (byte)99)
     {
         Mutations part1 = this.ParentObject.GetPart("Mutations") as Mutations;
         if (!part1.HasMutation("LiquidSpitter"))
         {
             part1.AddMutation((BaseMutation) new LiquidSpitter(LiquidVolume.ComponentLiquidTypes[this.newLiquid].GetName((LiquidVolume)null).Substring(2)), 1);
         }
         LiquidSpitter mutation = part1.GetMutation("LiquidSpitter") as LiquidSpitter;
         mutation.extraLiquids.Add(this.newLiquid);
         if (mutation.extraLiquids.Count == 1 && this.newLiquid == (byte)18)
         {
             mutation.extraLiquids.Add((byte)0);
         }
         this.ComponentLiquids.Add(this.newLiquid);
         string displayName = this.ParentObject.DisplayName;
         this.ParentObject.DisplayName = string.Empty;
         foreach (byte componentLiquid in this.ComponentLiquids)
         {
             GameObject parentObject = this.ParentObject;
             parentObject.DisplayName = parentObject.DisplayName + LiquidVolume.ComponentLiquidTypes[componentLiquid].GetAdjective((LiquidVolume)null) + "&y ";
         }
         GameObject parentObject1 = this.ParentObject;
         parentObject1.DisplayName = parentObject1.DisplayName + Evolution.GetPrefix(this.ComponentLiquids.Count) + "sludge";
         if (this.ComponentLiquids.Count >= 5)
         {
             JournalAPI.AddAccomplishment("You witnessed the rare formation of " + Grammar.A(Evolution.GetPrefix(this.ComponentLiquids.Count) + "sludge", false) + ".", "general", (string)null, -1L);
         }
         MessageQueue.AddPlayerMessage("The " + LiquidVolume.ComponentLiquidTypes[this.newLiquid].GetName((LiquidVolume)null) + " &ycatalyzes " + this.ParentObject.the + displayName + " into " + this.ParentObject.a + this.ParentObject.DisplayName + ".");
         bool flag  = false;
         Body part2 = this.ParentObject.GetPart <Body>();
         foreach (BodyPart bodyPart in part2.GetPart("Hand"))
         {
             if (bodyPart.Equipped == null)
             {
                 flag = true;
                 break;
             }
         }
         if (!flag)
         {
             this.totalHands += 2;
             BodyPart body        = part2.GetBody();
             BodyPart InsertAfter = body.AddPartAt("Pseudopod", 0, (string)null, (string)null, (string)null, (string)null, new int?(), new int?(), new int?(), new bool?(), new bool?(), new bool?(), new bool?(), new bool?(), "Hand", "Missile Weapon");
             body.AddPartAt(InsertAfter, "Pseudopod", 0, (string)null, (string)null, (string)null, (string)null, new int?(), new int?(), new int?(), new bool?(), new bool?(), new bool?(), new bool?(), new bool?());
         }
         if (this.newLiquid == (byte)0)
         {
             this.ParentObject.TakeObject("Watery Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)1)
         {
             this.ParentObject.TakeObject("Salty Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)2)
         {
             this.ParentObject.TakeObject("Tarry Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)3)
         {
             this.ParentObject.TakeObject("Magmatic Pseudopod", false, new int?(0));
             this.ParentObject.Statistics["HeatResistance"].BaseValue += 100;
             this.ParentObject.pPhysics.Temperature = 1000;
         }
         else if (this.newLiquid == (byte)4)
         {
             this.ParentObject.TakeObject("Slimy Pseudopod", false, new int?(0));
             this.ParentObject.AddPart <DisarmOnHit>(new DisarmOnHit(100), true);
         }
         else if (this.newLiquid == (byte)5)
         {
             this.ParentObject.TakeObject("Oily Pseudopod", false, new int?(0));
             this.ParentObject.AddPart <DisarmOnHit>(new DisarmOnHit(100), true);
         }
         else if (this.newLiquid == (byte)6)
         {
             this.ParentObject.TakeObject("Bloody Pseudopod", false, new int?(0));
             this.ParentObject.AddPart <LifeDrainOnHit>(new LifeDrainOnHit("15-20", 100), true);
         }
         else if (this.newLiquid == (byte)7)
         {
             this.ParentObject.TakeObject("Acidic Pseudopod", false, new int?(0));
             this.ParentObject.Statistics["AcidResistance"].BaseValue += 100;
         }
         else if (this.newLiquid == (byte)8)
         {
             this.ParentObject.TakeObject("Honeyed Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)9)
         {
             this.ParentObject.TakeObject("Lush Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)10)
         {
             this.ParentObject.TakeObject("Sludgy Pseudopod2", false, new int?(0));
         }
         else if (this.newLiquid == (byte)11)
         {
             this.ParentObject.TakeObject("Gooey Pseudopod2", false, new int?(0));
         }
         else if (this.newLiquid == (byte)12)
         {
             this.ParentObject.TakeObject("Putrid Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)13)
         {
             this.ParentObject.TakeObject("Unctuous Pseudopod", false, new int?(0));
             this.ParentObject.AddPart <DisarmOnHit>(new DisarmOnHit(100), true);
         }
         else if (this.newLiquid == (byte)14)
         {
             this.ParentObject.TakeObject("Oozing Pseudopod2", false, new int?(0));
         }
         else if (this.newLiquid == (byte)15)
         {
             this.ParentObject.TakeObject("Spiced Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)16)
         {
             this.ParentObject.TakeObject("Luminous Pseudopod2", false, new int?(0));
             this.ParentObject.AddPart <LightSource>(new LightSource(), true);
             (this.ParentObject.GetPart("LightSource") as LightSource).Radius = 6;
             this.ParentObject.Statistics["ColdResistance"].BaseValue        += 100;
         }
         else if (this.newLiquid == (byte)17)
         {
             this.ParentObject.TakeObject("Neutronic Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)18)
         {
             this.ParentObject.TakeObject("Homogenized Pseudopod", false, new int?(0));
             this.ParentObject.AddPart <CloneOnHit>(new CloneOnHit(), true);
         }
         else if (this.newLiquid == (byte)20)
         {
             this.ParentObject.TakeObject("Waxen Pseudopod", false, new int?(0));
         }
         else if (this.newLiquid == (byte)21)
         {
             this.ParentObject.TakeObject("Inky Pseudopod", false, new int?(0));
             this.ParentObject.AddPart <DisarmOnHit>(new DisarmOnHit(100), true);
         }
         else if (this.newLiquid == (byte)22)
         {
             this.ParentObject.TakeObject("Sugary Pseudopod", false, new int?(0));
         }
         this.ParentObject.pBrain.PerformReequip(false);
         this.newLiquid = (byte)99;
     }
     this.isCatalyzing = false;
     if (this.ComponentLiquids.Count != 1)
     {
         return;
     }
     MessageQueue.AddPlayerMessage("The reacting liquids congeal into a " + this.ParentObject.ShortDisplayName + ".");
     this.C.AddObject(this.ParentObject);
     XRLCore.Core.Game.ActionManager.AddActiveObject(this.ParentObject);
 }
Example #10
0
 public override bool FireEvent(Event E)
 {
     if (E.ID == "EndTurnEngulfing")
     {
         if (descriptionSet == false)
         {
             IPart.ThePlayer.GetPart <Description>().Short = "I'm not a bad slime";
             descriptionSet = true;
         }
         GameObject parameter = E.GetParameter <GameObject>("Object");
         if (parameter != null)
         {
             Damage damage = new Damage(Stat.Random(IPart.ThePlayer.Statistics["Toughness"].BaseValue / 2, IPart.ThePlayer.Statistics["Toughness"].BaseValue));
             Event  E1     = Event.New("TakeDamage", 0, 0, 0);
             E1.AddParameter("Damage", (object)damage);
             E1.AddParameter("Owner", (object)this.ParentObject);
             E1.AddParameter("Attacker", (object)this.ParentObject);
             E1.AddParameter("Message", this.DamageMessage);
             parameter.FireEvent(E1);
             if (parameter.hitpoints <= 0)
             {
                 if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&wAverage")
                 {
                     this.statGains(1);
                 }
                 else if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&WTough")
                 {
                     this.statGains(2);
                 }
                 else if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&rVery Tough")
                 {
                     this.statGains(4);
                 }
                 else if (DifficultyEvaluation.GetDifficultyDescription(parameter) == "&RImpossible")
                 {
                     this.statGains(8);
                 }
                 Mutations targetMutations = parameter.GetPart <Mutations>();
                 Mutations playerMutations = IPart.ThePlayer.GetPart <Mutations>();
                 if (targetMutations != null)
                 {
                     bool   CasterIsPlayer = XRLCore.Core.Game.Player.Body == this.ParentObject ? true : false;
                     string PopupText;
                     foreach (BaseMutation mutation in targetMutations.MutationList)
                     {
                         //mutation.GetStat() == "Ego"
                         if (!playerMutations.HasMutation(mutation) && mutation.CompatibleWith(this.ParentObject))
                         {
                             if (mutation.GetMutationEntry().Category.Name == "Mental")
                             {
                                 PopupText = "Integrate Mental mutation with name of " + mutation.Name;
                                 if (CasterIsPlayer || UI.Popup.ShowYesNoCancel(PopupText) == DialogResult.Yes)
                                 {
                                     playerMutations.AddMutation(mutation, 1);
                                 }
                             }
                             else if (CasterIsPlayer && ForbiddenMutations.Contains(mutation.Name))//Forbidden Mutations
                             {
                                 if (mutation.AffectsBodyParts())
                                 {
                                     PopupText = "Integrate Forbidden-" + mutation.GetMutationEntry().Category.Name + " BodyBased mutation with name of " + mutation.Name;
                                 }
                                 else
                                 {
                                     PopupText = "Integrate Forbidden-" + mutation.GetMutationEntry().Category.Name + " mutation with name of " + mutation.Name;
                                 }
                                 if (UI.Popup.ShowYesNoCancel(PopupText) == DialogResult.Yes)
                                 {
                                     playerMutations.AddMutation(mutation, 1);
                                 }
                             }
                         }
                     }
                 }
                 Stomach part = IPart.ThePlayer.GetPart <Stomach>();
                 IPart.ThePlayer.RemoveEffect("Famished", false);
                 part.HungerLevel    = 0;
                 part.CookCount      = 0;
                 part.CookingCounter = 0;
                 part.Water          = 30000;
             }
         }
     }
     return(true);
 }
Example #11
0
        public override bool FireEvent(Event E)
        {
            if (E.ID == "ApplyTonic")
            {
                GameObject target = E.GetGameObjectParameter("Target");
                target.PermuteRandomMutationBuys();
                var       Messages  = new List <string>();
                var       gainLimb  = false;
                Mutations mutations = null;
                if (target.IsPlayer())
                {
                    Popup.Show("As the tonic floods your veins, you feel the latent genetic pressure of eons.");
                }
                if (ParentObject.HasPart("Temporary") && !target.HasPart("Temporary"))
                {
                    Messages.Add((target.IsPlayer() ? "Your" :
                                  Grammar.MakePossessive(target.The + target.ShortDisplayName)) +
                                 " genes ache longingly.");
                }
                else
                {
                    var Random    = Utility.Random(this, target);
                    var goodColor = ColorCoding.ConsequentialColor(ColorAsGoodFor: target);
                    var badColor  = ColorCoding.ConsequentialColor(ColorAsBadFor: target);
                    if (target.IsTrueKin())
                    {
                        var which = new[] { "Strength", "Agility", "Toughness" }.GetRandomElement(Random);
                        if (target.HasStat(which))
                        {
                            ++target.Statistics[which].BaseValue;
                            Messages.Add(goodColor +
                                         (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                         target.GetVerb("gain") + " 1 point of " + which + "!");
                        }
                    }
                    else   /*if mutant*/
                    {
                        mutations = target.GetPart <Mutations>();
                        if (target.IsEsper())
                        {
                            // can't chimerify; reduce glimmer instead
                            int glimmerReduction = Random.Next(1, 5);
                            int currentGlimmer   = target.GetPsychicGlimmer();
                            if (glimmerReduction > currentGlimmer)
                            {
                                glimmerReduction = currentGlimmer;
                            }
                            _ = target.ModIntProperty("GlimmerModifier", -glimmerReduction);
                            target.SyncMutationLevelAndGlimmer();
                            Messages.Add("Nerves weave and ossify, unable to escape " +
                                         (target.IsPlayer() ? "your" : Grammar.MakePossessive(target.the + target.ShortDisplayName)) +
                                         " psychic cage.");
                        }
                        else if (!target.IsChimera())
                        {
                            var mentals       = target.GetMentalMutations();
                            var mentalDefects = target.GetMutationsOfCategory("MentalDefects");
                            var mpToTransfer  = 0;
                            if (mentals.Count > 0 || mentalDefects.Count > 0)
                            {
                                Messages.Add((target.IsPlayer() ? "Your" :
                                              Grammar.MakePossessive(target.The + target.ShortDisplayName)) +
                                             " genome sloughs off superfluous layers of alien thoughtstuff.");
                                Messages.Add("");
                            }
                            if (mentals.Count > 0)
                            {
                                // choose 1d4 MP of investment in mental mutations to remove...
                                mpToTransfer = Random.Next(1, 5);
                                var totalLevels = mentals.Map(m => m.BaseLevel).Sum();
                                var toReduce    = new List <Tuple <BaseMutation, int> >(mpToTransfer);
                                if (totalLevels <= mpToTransfer)
                                {
                                    // remove everything, will be eligible for Chimera
                                    mpToTransfer = totalLevels;
                                    foreach (var mental in mentals)
                                    {
                                        toReduce.Add(Tuple.Create(mental, mental.BaseLevel));
                                    }
                                }
                                else
                                {
                                    // magically pick mpToTransfer mutations weighted by level
                                    var remainingLevels    = totalLevels;
                                    var remainingReduction = mpToTransfer;
                                    foreach (var mental in mentals)
                                    {
                                        var thisMentalReduction = 0;
                                        while (0 < remainingReduction && Random.Next(0, remainingLevels) < mental.BaseLevel - thisMentalReduction + remainingReduction - 1)
                                        {
                                            ++thisMentalReduction;
                                            --remainingLevels;
                                            --remainingReduction;
                                        }
                                        if (0 < thisMentalReduction)
                                        {
                                            toReduce.Add(Tuple.Create(mental, thisMentalReduction));
                                        }
                                        remainingLevels -= mental.BaseLevel - thisMentalReduction;
                                        if (0 >= remainingReduction)
                                        {
                                            break;
                                        }
                                    }
                                }
                                // ... remove them...
                                var lostMentals = new List <MutationEntry>();
                                foreach (var mental in toReduce)
                                {
                                    var mutation  = mental.Item1;
                                    var reduction = mental.Item2;
                                    if (mutation.BaseLevel <= reduction)
                                    {
                                        // remove the mutation altogether
                                        lostMentals.Add(mutation.GetMutationEntry());
                                        mutations.RemoveMutation(mutation);
                                    }
                                    else
                                    {
                                        // reduce the mutation level
                                        mutations.LevelMutation(mutation, mutation.BaseLevel - reduction);
                                    }
                                }
                                // ... and replace any lost mental mutations with physical mutations
                                foreach (var mental in lostMentals)
                                {
                                    // expensive to regenerate this each time, but won't be very many times and
                                    // want to make sure exclusions from e.g. Stinger are handled correctly
                                    Messages.Add(badColor +
                                                 (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                 target.GetVerb("lose") + " " + mental.DisplayName + "!");
                                    var eligiblePhysicals = mutations.GetMutatePool(m => m.Category.Name.EndsWith("Physical")).Shuffle(Random);
                                    var similarPhysicals  = eligiblePhysicals.Where(p => p.Cost == mental.Cost);
                                    var otherPhysicals    = eligiblePhysicals.Where(p => p.Cost != mental.Cost);
                                    foreach (var physical in similarPhysicals.Concat(otherPhysicals))
                                    {
                                        _ = mutations.AddMutation(physical, 1);
                                        Messages.Add(goodColor +
                                                     (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                     target.GetVerb("gain") + " " + physical.DisplayName + "!");
                                        --mpToTransfer;
                                        break;
                                    } // else if there are no valid physical mutations, don't add anything new
                                }
                            }
                            while (0 < mpToTransfer)
                            {
                                var          physicals        = target.GetPhysicalMutations();
                                BaseMutation which            = null;
                                var          canLevelNormally = physicals.Where(m => m.CanIncreaseLevel());
                                if (canLevelNormally.Any())
                                {
                                    which = canLevelNormally.GetRandomElement(Random);
                                }
                                else
                                {
                                    var underMaxLevel = physicals.Where(m => m.BaseLevel < m.MaxLevel);
                                    if (underMaxLevel.Any())
                                    {
                                        which = underMaxLevel.GetRandomElement(Random);
                                    }
                                }
                                if (which != null)
                                {
                                    mutations.LevelMutation(which, which.BaseLevel + 1);
                                    --mpToTransfer;
                                }
                                else
                                {
                                    // no physical mutations to put the levels in, spend the rest on a new one
                                    foreach (var physical in mutations.GetMutatePool(m => m.Category.Name.EndsWith("Physical")).Shuffle(Random))
                                    {
                                        _ = mutations.AddMutation(physical, 1);
                                        Messages.Add(goodColor +
                                                     (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                     target.GetVerb("gain") + " " + physical.DisplayName + "!");
                                        break;
                                    }
                                    mpToTransfer = 0;
                                }
                            }
                            if (target.GetMentalMutations().Count == 0)
                            {
                                foreach (var mutation in mentalDefects)
                                {
                                    mutations.RemoveMutation(mutation);

                                    var mental = mutation.GetMutationEntry();
                                    Messages.Add(goodColor +
                                                 (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                 target.GetVerb("lose") + " " + mental.DisplayName + "!");

                                    var eligibleDefects = MutationFactory.GetMutationsOfCategory("PhysicalDefects").Shuffle(Random);
                                    var similarDefects  = eligibleDefects.Where(p => p.Cost == mental.Cost);
                                    var otherDefects    = eligibleDefects.Where(p => p.Cost != mental.Cost);
                                    foreach (var physical in similarDefects.Concat(otherDefects))
                                    {
                                        _ = mutations.AddMutation(physical, 1);
                                        Messages.Add(badColor +
                                                     (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                     target.GetVerb("gain") + " " + physical.DisplayName + "!");
                                        break;
                                    } // else if there are no valid physical defects, don't add anything new
                                }

                                target.Property["MutationLevel"] =
                                    target.Property.GetValueOrDefault("MutationLevel", "") + "Chimera";
                                Messages.Add("");
                                Messages.Add(goodColor +
                                             (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                             target.GetVerb("become") + " a Chimera!");
                            }
                        }
                        else   /*target.IsChimera*/
                        {
                            // 50% chance of new limb, 50% chance of mutation level gain
                            if (Random.Next(2) == 0)
                            {
                                // new limb! defer until the other messages are shown to actually gain it
                                gainLimb = true;
                            }
                            else
                            {
                                var physicals = target.GetPhysicalMutations().Where(m => m.CanLevel());
                                if (physicals.Any())
                                {
                                    // +1 to level of a physical mutation, uncapped
                                    var          which  = physicals.GetRandomElement(Random);
                                    const string source = "{{r-r-r-R-R-W distribution|limbic fluid}} injections";
                                    var          found  = false;
                                    foreach (var mod in mutations.MutationMods)
                                    {
                                        if (mod.sourceName == source && mod.mutationName == which.Name)
                                        {
                                            ++mod.bonus;
                                            found = true;
                                        }
                                    }
                                    if (!found)
                                    {
                                        _ = mutations.AddMutationMod(which.Name, 1, Mutations.MutationModifierTracker.SourceType.StatMod, source);
                                    }
                                    Messages.Add(goodColor +
                                                 (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                 target.GetVerb("gain") + " one rank of " + which.DisplayName + "!");
                                }
                                else
                                {
                                    // +1 MP if we can't level anything
                                    target.GainMP(1);
                                    Messages.Add(goodColor +
                                                 (target.IsPlayer() ? "You" : target.The + target.ShortDisplayName) +
                                                 target.GetVerb("gain") + " one MP!");
                                }
                            }
                        }
                    }
                }
                if (target.IsPlayer() && Messages.Count > 0)
                {
                    var output = string.Join("\n", Messages);
                    output = _extraLines.Replace(output, "\n\n");
                    Popup.Show(output);
                }
                else
                {
                    foreach (var Message in Messages)
                    {
                        AddPlayerMessage(Message);
                    }
                }
                if (gainLimb)
                {
                    _ = mutations.AddChimericBodyPart();
                }
            }
            return(base.FireEvent(E));
        }