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); }
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); }
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; } } }
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); } }
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); }
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; } } } } }
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); }