Example #1
0
        public void ApplyMutation(Pawn pawn, HediffRadiation radiation)
        {
            if (radiation.normal + radiation.rare <= def.mutateThreshold.RandomInRange)
            {
                return;
            }

            float ratio = radiation.rare / (radiation.normal + radiation.rare);

            radiation.rare   = 0;
            radiation.normal = 0;

            SpawnMutation(pawn, radiation.Part, ratio, radiation);
        }
Example #2
0
        public void ApplyBurn(Pawn pawn, HediffRadiation radiation)
        {
            float burnAmount = def.burnThreshold.RandomInRange;

            if (radiation.burn < burnAmount)
            {
                return;
            }

            radiation.burn -= burnAmount;

            DamageInfo dinfo = new DamageInfo(DamageDefOf.Burn, burnAmount, 999999f, -1f, this, radiation.Part, null, DamageInfo.SourceCategory.ThingOrUnknown, null);

            pawn.TakeDamage(dinfo);

            RadiologyEffectSpawnerDef.Spawn(def.burnEffect, pawn);
        }
Example #3
0
        public void SpawnMutation(Pawn pawn, BodyPartRecord part, float ratio, HediffRadiation radiation = null)
        {
            Mutation mutation;
            var      mutatedParts = RadiationHelper.MutatePawn(pawn, part, ratio, out mutation);

            lastMutation     = mutation.def;
            lastMutationTick = Find.TickManager.TicksGame;
            if (mutatedParts == null)
            {
                return;
            }

            foreach (var anotherRadiation in pawn.health.hediffSet.GetHediffs <HediffRadiation>())
            {
                if (mutatedParts.Contains(anotherRadiation.Part) && radiation != anotherRadiation)
                {
                    anotherRadiation.normal -= def.mutateThreshold.min * (1f - ratio);
                    anotherRadiation.rare   -= def.mutateThreshold.min * ratio;
                }
            }
        }
Example #4
0
        public void Irradiate(Pawn pawn, int ticksCooldown)
        {
            this.ticksCooldown = ticksCooldown;
            currentUser        = pawn;

            radiationTracker.Clear();

            Room room       = Position.GetRoom(Map);
            Pawn actualPawn = Map.mapPawns.AllPawns.Where(x => x.GetRoom() == room).RandomElementWithFallback(pawn);

            foreach (CompIrradiator comp in GetIrradiators())
            {
                RadiationInfo info = new RadiationInfo {
                    chamberDef = def, pawn = actualPawn, part = GetBodyPart(actualPawn), secondHand = actualPawn != pawn, visited = new HashSet <CompIrradiator>()
                };
                comp.Irradiate(this, info, ticksCooldown);
                radiationTracker.burn   += info.burn;
                radiationTracker.normal += info.normal;
                radiationTracker.rare   += info.rare;

                if (actualPawn.IsShielded())
                {
                    continue;
                }

                HediffRadiation radiation = RadiationHelper.GetHediffRadition(info.part, info.pawn);
                if (radiation == null)
                {
                    continue;
                }

                radiation.burn   += info.burn;
                radiation.normal += info.normal;
                radiation.rare   += info.rare;

                ApplyBurn(actualPawn, radiation);
                ApplyMutation(actualPawn, radiation);
            }
        }
Example #5
0
        public HediffRadiation GetHediffRadition(BodyPartRecord part, Chamber chamber, Pawn pawn)
        {
            if (part == null)
            {
                return(null);
            }

            foreach (var v in pawn.health.hediffSet.GetHediffs <HediffRadiation>())
            {
                if (v.Part == part)
                {
                    return(v);
                }
            }
            HediffRadiation hediff = HediffMaker.MakeHediff(HediffDefOf.RadiologyRadiation, pawn, part) as HediffRadiation;

            if (hediff == null)
            {
                return(hediff);
            }

            pawn.health.AddHediff(hediff, null, null, null);
            return(hediff);
        }
Example #6
0
        public void Irradiate(RadiationInfo info, int ticks)
        {
            Chamber chamber = parent.Linked <Chamber>();

            SoundDefOf.RadiologyIrradiateBasic.PlayOneShot(new TargetInfo(parent.Position, parent.Map, false));
            ticksCooldown = ticks;

            if (info.pawn.IsShielded())
            {
                return;
            }

            info.part   = GetBodyPart(info.chamber, info.pawn);
            info.burn   = props.burn.perSecond.RandomInRange;
            info.normal = props.mutate.perSecond.RandomInRange;
            info.rare   = props.mutateRare.perSecond.RandomInRange;
            if (info.secondHand)
            {
                info.rare /= 2;
            }

            motesReflectAt.Clear();
            foreach (ThingComp comp in GetModifiers <ThingComp, IRadiationModifier>(info.chamber))
            {
                if (comp is CompBlocker)
                {
                    motesReflectAt.Add((parent.Rotation.IsHorizontal ? comp.parent.Position.x : comp.parent.Position.z) + 0.5f);
                }

                if (info.secondHand)
                {
                    continue;
                }

                IRadiationModifier modifier = comp as IRadiationModifier;
                modifier.Modify(ref info);
            }

            if (info.burn <= 0 && info.normal <= 0 && info.rare <= 0)
            {
                return;
            }

            HediffRadiation radiation = GetHediffRadition(info.part, info.chamber, info.pawn);

            if (radiation == null)
            {
                return;
            }

            radiation.burn   += info.burn;
            radiation.normal += info.normal;
            radiation.rare   += info.rare;

            float burnThreshold = info.chamber.def.burnThreshold.RandomInRange;
            float burnAmount    = radiation.burn - burnThreshold;

            if (burnAmount > 0)
            {
                radiation.burn -= info.chamber.def.burnThreshold.min;

                DamageInfo dinfo = new DamageInfo(DamageDefOf.Burn, burnAmount * props.burn.multiplier, 999999f, -1f, info.chamber, radiation.Part, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                info.pawn.TakeDamage(dinfo);

                if (chamber != null)
                {
                    RadiologyEffectSpawnerDef.Spawn(chamber.def.burnEffect, info.pawn);
                }
            }

            float mutateThreshold = info.chamber.def.mutateThreshold.RandomInRange;
            float mutateAmount    = radiation.normal + radiation.rare - mutateThreshold;

            if (mutateAmount > 0)
            {
                float ratio = radiation.rare / (radiation.normal + radiation.rare);
                radiation.rare   -= info.chamber.def.mutateThreshold.min * ratio;
                radiation.normal -= info.chamber.def.mutateThreshold.min * (1f - ratio);

                Mutation mutation;
                var      mutatedParts = RadiationHelper.MutatePawn(info.pawn, radiation, mutateAmount * props.mutate.multiplier, ratio, out mutation);
                if (mutatedParts != null)
                {
                    foreach (var anotherRadiation in info.pawn.health.hediffSet.GetHediffs <HediffRadiation>())
                    {
                        if (mutatedParts.Contains(anotherRadiation.Part) && radiation != anotherRadiation)
                        {
                            anotherRadiation.normal -= info.chamber.def.mutateThreshold.min * (1f - ratio);
                            anotherRadiation.rare   -= info.chamber.def.mutateThreshold.min * ratio;
                        }
                    }
                }
            }
        }
Example #7
0
        public static IEnumerable <BodyPartRecord> MutatePawn(Pawn pawn, HediffRadiation radiation, float mutateAmount, float rareRatio, out Mutation mutationResult)
        {
            mutationResult = null;

            BodyPartRecord part = radiation.Part;

            Debug.Log("Finding mutation for part: " + part);
            Debug.Log("Rare ratio: " + rareRatio);

            Dictionary <string, HashSet <BodyPartDef> >    excludedPartDefsForTag = new Dictionary <string, HashSet <BodyPartDef> >();
            Dictionary <string, HashSet <BodyPartRecord> > excludedPartsForTag    = new Dictionary <string, HashSet <BodyPartRecord> >();

            foreach (Mutation existingMutation in pawn.health.hediffSet.GetHediffs <Mutation>())
            {
                foreach (string tag in existingMutation.def.exclusives)
                {
                    HashSet <BodyPartDef> setDef = excludedPartDefsForTag.TryGetValue(tag);
                    if (setDef == null)
                    {
                        excludedPartDefsForTag[tag] = setDef = new HashSet <BodyPartDef>();
                    }
                    setDef.Add(existingMutation.Part.def);

                    HashSet <BodyPartRecord> set = excludedPartsForTag.TryGetValue(tag);
                    if (set == null)
                    {
                        excludedPartsForTag[tag] = set = new HashSet <BodyPartRecord>();
                    }
                    set.Add(existingMutation.Part);
                }
            }

            Debug.Log("Excluded parts for tags: " + Debug.AsText(excludedPartsForTag));
            Debug.Log("Excluded defs for tags: " + Debug.AsText(excludedPartDefsForTag));

            var mutations =
                MutationsHelper.Mutations.Where(x => x.relatedParts == null || x.relatedParts.Contains(part.def));

            Debug.Log("All applicable mutations: " + Debug.AsText(mutations));

            Dictionary <HediffMutationDef, IEnumerable <BodyPartRecord> > allowedMutations = new Dictionary <HediffMutationDef, IEnumerable <BodyPartRecord> >();

            foreach (var mutation in mutations)
            {
                var parts = WhichPartsMutationIsAllowedOn(pawn, mutation, part, excludedPartDefsForTag, excludedPartsForTag);
                Debug.Log("  " + mutation + ": to " + Debug.AsText(parts));

                if (parts.Count() == 0)
                {
                    continue;
                }
                allowedMutations[mutation] = parts;
            }

            Debug.Log("All allowed mutations: " + Debug.AsText(allowedMutations));
            if (allowedMutations.Count() == 0)
            {
                Debug.Log("No mutation possible!");
                return(null);
            }

            HediffMutationDef mutationDef = allowedMutations.Keys.RandomElementByWeight(x => (float)Math.Pow(x.likelihood, 1f - rareRatio));

            Debug.Log("Chose mutation: " + mutationDef);

            var applicableParts = allowedMutations[mutationDef];

            Debug.Log("Can be applied to body parts: " + Debug.AsText(applicableParts));

            if (allowedMutations.Count() == 0)
            {
                Debug.Log("No matching body parts!");
                return(null);
            }

            var chosenPart = applicableParts.RandomElement();

            Debug.Log("Chose part: " + chosenPart);

            var chosenParts = pawn.health.hediffSet.GetNotMissingParts()
                              .Where(x => mutationDef.affectsAllParts ? x.def == chosenPart.def : x == chosenPart);

            foreach (var partToMutate in chosenParts)
            {
                Debug.Log("Adding to part: " + partToMutate);

                if (pawn.health.hediffSet.GetHediffs <Mutation>().Where(x => x.def == mutationDef && x.Part == partToMutate).Any())
                {
                    Debug.Log("  But it already has this mutation!");
                    continue;
                }

                Mutation mutation = HediffMaker.MakeHediff(mutationDef, pawn, partToMutate) as Mutation;
                if (mutation == null)
                {
                    continue;
                }

                mutationResult = mutation;
                pawn.health.AddHediff(mutation, partToMutate, null, null);
            }


            return(chosenParts);
        }