public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { // part = brain var spine = pawn.health.hediffSet.GetSpine(); bool isClean = MedicalRecipesUtility.IsClean(pawn, part); bool isViolation = IsViolationOnPawn(pawn, part, Faction.OfPlayer); if (billDoer != null) { if (CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, billDoer, pawn); GenSpawn.Spawn(AutomataRaceDefOf.PN_Brain, billDoer.Position, billDoer.Map); } pawn.TakeDamage(new DamageInfo(DamageDefOf.SurgicalCut, 99999f, 999f, -1f, null, part)); pawn.health.AddHediff(HediffDefOf.MissingBodyPart, spine, new DamageInfo(DamageDefOf.SurgicalCut, 99999f, 999f, -1f, null, spine)); if (isClean) { if (pawn.Dead) { ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); } ThoughtUtility.GiveThoughtsForPawnOrganHarvested(pawn); } if (isViolation) { ReportViolation(pawn, billDoer, pawn.FactionOrExtraMiniOrHomeFaction, -70, "GoodwillChangedReason_RemovedBodyPart".Translate(part.LabelShort)); } }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { bool flag1 = MedicalRecipesUtility.IsClean(pawn, part); bool flag2 = this.IsViolationOnPawn(pawn, part, Faction.OfPlayer); if (billDoer != null) { if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] { billDoer, pawn }); MedicalRecipesUtility.SpawnNaturalPartIfClean(pawn, part, billDoer.Position, billDoer.Map); MedicalRecipesUtility.SpawnThingsFromHediffs(pawn, part, billDoer.Position, billDoer.Map); } DamageDef surgicalCut = DamageDefOf.SurgicalCut; float amount = 99999f; float armorPenetration = 999f; pawn.TakeDamage(new DamageInfo(surgicalCut, amount, armorPenetration, -1f, null, part, null, DamageInfo.SourceCategory.ThingOrUnknown, null)); if (flag1) { if (pawn.Dead) { ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); } ThoughtUtility.GiveThoughtsForPawnOrganHarvested(pawn); } if (flag2 && pawn.Faction != null && billDoer != null && billDoer.Faction != null) { Faction faction = pawn.Faction; Faction faction2 = billDoer.Faction; int goodwillChange = -15; string reason = "GoodwillChangedReason_RemovedBodyPart".Translate(part.LabelShort); GlobalTargetInfo?lookTarget = new GlobalTargetInfo?(pawn); faction.TryAffectGoodwillWith(faction2, goodwillChange, true, true, reason, lookTarget); } }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { base.ApplyOnPawn(pawn, part, billDoer, ingredients, bill); bool flag = MedicalRecipesUtility.IsClean(pawn, part); bool flag2 = this.IsViolationOnPawn(pawn, part, Faction.OfPlayer); if (billDoer != null) { if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] { billDoer, pawn }); Thing md = ThingMaker.MakeThing(WTH_DefOf.WTH_ExtractedBrainData); md.stackCount = 3 + pawn.skills.GetSkill(SkillDefOf.Intellectual).Level; GenPlace.TryPlaceThing(md, pawn.Position, pawn.Map, ThingPlaceMode.Near); } DamageDef surgicalCut = DamageDefOf.SurgicalCut; float amount = 99999f; float armorPenetration = 999f; pawn.TakeDamage(new DamageInfo(surgicalCut, amount, armorPenetration, -1f, null, part, null, DamageInfo.SourceCategory.ThingOrUnknown, null)); if (flag) { if (pawn.Dead) { ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); } ThoughtUtility.GiveThoughtsForPawnOrganHarvested(pawn); } if (flag2 && pawn.Faction != null && billDoer != null && billDoer.Faction != null) { Faction arg_120_0 = pawn.Faction; Faction faction = billDoer.Faction; int goodwillChange = -15; string reason = "GoodwillChangedReason_RemovedBodyPart".Translate(part.LabelShort); GlobalTargetInfo?lookTarget = new GlobalTargetInfo?(pawn); arg_120_0.TryAffectGoodwillWith(faction, goodwillChange, true, true, reason, lookTarget); } }
private void DoSocialImpact(Pawn victim) { var isPrisoner = victim.IsPrisonerOfColony; var giveThought = AllowToolUtility.PawnIsFriendly(victim); if (giveThought) { ThoughtUtility.GiveThoughtsForPawnExecuted(victim, PawnExecutionKind.GenericBrutal); } if (victim.RaceProps != null && victim.RaceProps.intelligence == Intelligence.Animal) { pawn.records.Increment(RecordDefOf.AnimalsSlaughtered); } if (isPrisoner) { TaleRecorder.RecordTale(TaleDefOf.ExecutedPrisoner, pawn, victim); } }
public override void ApplyOnPawn(Pawn p, BodyPartRecord part, Pawn doer, List <Thing> ingredients, Bill bill) { var har = is_harvest(p, part); base.ApplyOnPawn(p, part, doer, ingredients, bill); if (har) { if (!p.Dead) { ThoughtUtility.GiveThoughtsForPawnOrganHarvested(p); } else { ThoughtUtility.GiveThoughtsForPawnExecuted(p, PawnExecutionKind.OrganHarvesting); } } }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnAggroMentalState(TargetIndex.A); yield return(Toils_Interpersonal.GotoPrisoner(pawn, Victim, PrisonerInteractionModeDefOf.Execution).FailOn(() => !Victim.IsPrisonerOfColony || !Victim.guest.PrisonerIsSecure)); Toil execute = new Toil(); execute.initAction = delegate { ExecutionUtility.DoExecutionByCut(execute.actor, Victim); ThoughtUtility.GiveThoughtsForPawnExecuted(Victim, PawnExecutionKind.GenericBrutal); TaleRecorder.RecordTale(TaleDefOf.ExecutedPrisoner, new object[] { pawn, Victim }); }; execute.defaultCompleteMode = ToilCompleteMode.Instant; yield return(execute); }
/*public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List<Thing> ingredients, Bill bill) * { * if (billDoer != null) * { * DamageDef surgicalCut = DamageDefOf.SurgicalCut; * int amount = 99999; * pawn.TakeDamage(new DamageInfo(surgicalCut, amount, -1f, null, pawn.health.hediffSet.GetBrain(), null, DamageInfo.SourceCategory.ThingOrUnknown)); * ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); * } * }*/ public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { if (billDoer != null) { if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } if (pawn.relations.OpinionOf(billDoer) < 60) { Messages.Message("PolarisMessageFailedMakeCartridge".Translate(pawn.LabelShort, billDoer.LabelShort), pawn, MessageTypeDefOf.NegativeEvent); return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, billDoer, pawn); ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, billDoer, PawnExecutionKind.OrganHarvesting); GenSpawn.Spawn(PolarisblocDefOf.PolarisCartridge, billDoer.Position, billDoer.Map); pawn.apparel.DropAll(billDoer.Position); pawn.DeSpawn(); pawn.Kill(null); //Find.WorldPawns.PassToWorld(pawn, PawnDiscardDecideMode.Discard); //pawn.Destroy(); } }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { bool flag = MedicalRecipesUtility.IsClean(pawn, part); bool flag2 = this.IsViolationOnPawn(pawn, part, Faction.OfPlayer); if (billDoer != null) { if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] { billDoer, pawn }); MedicalRecipesUtility.SpawnNaturalPartIfClean(pawn, part, billDoer.Position, billDoer.Map); MedicalRecipesUtility.SpawnThingsFromHediffs(pawn, part, billDoer.Position, billDoer.Map); } pawn.TakeDamage(new DamageInfo(DamageDefOf.SurgicalCut, 99999, -1f, null, part, null)); if (flag) { if (pawn.Dead) { ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); } else { ThoughtUtility.GiveThoughtsForPawnOrganHarvested(pawn); } } if (flag2) { pawn.Faction.AffectGoodwillWith(billDoer.Faction, -20f); } }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { //If the part has no injuries, it's torture -- otherwise it's emergency surgery bool torture = IsClean(pawn, part); //Technically, we could refine this a bit more... it's not necessary to chop a limb off because they // have a broken bone. However, this is a "good enough" solution. It starts to get to the point of // subjectiveness on whether the surgery was valid or not. ///Amount of pain and suffering caused by removal of this part. float maxDamage = (float)part.def.hitPoints / 37.5f; bool failed = false; if (billDoer != null) { failed = CheckSurgeryFail(billDoer, pawn, ingredients, part, bill); if (!failed) { TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object [] { billDoer, pawn }); } SpawnThingsFromHediffs(pawn, part, billDoer.Position, billDoer.Map); } //Always dismember the part regardless of success if (!pawn.health.hediffSet.PartIsMissing(part)) //make sure any surgery failure didn't already chop off the part for us... yay...? { var dinfo = new DamageInfo(failed ? DamageDefOf.Cut : DamageDefOf.SurgicalCut, part.def.hitPoints, -1f, null, part, null); pawn.TakeDamage(dinfo); //[imagine sound effect: dull, sticky thud] } if (failed) { //whoops, I think I snagged an artery float severity = UnityEngine.Random.Range(0f, maxDamage); if (!pawn.health.hediffSet.HasHediff(HediffDefOf.BloodLoss)) { pawn.health.AddHediff(HediffDefOf.BloodLoss, null, null); } HealthUtility.AdjustSeverity(pawn, HediffDefOf.BloodLoss, severity); //New in version 4: more filth! yay! int arterial_bleeding = (int)Math.Sqrt(severity * 50f); while (arterial_bleeding-- > 0) { if (pawn.RaceProps.IsFlesh) { pawn.health.DropBloodFilth(); } } } ///// Version 4 additions ///// //Add wounds to body part(s) containing the part in question (either the next higher joint for a limb, or the surrounding body part for an organ) //If removing a cube, we need an opening as large as one of its sides (which is the 2/3 power -- 1/3 power is incision, 2/3 power is hole, 3/3 power is full avulsion) //Since most body parts in real life tend toward flat and oblong this isn't the best rule of thumb to follow, but it works great for its inherent simplicity. //e.g., to remove lung (20 HP) we will cause 1+floor(20**2/3) = 8 HP of damage to the torso to get it out bool reachedsurface = false; //(part.depth != BodyPartDepth.Inside); var currentpart = part.parent; int partdamage = 1 + (int)(Math.Pow(part.def.hitPoints * part.def.hitPoints, 0.33333)); while (partdamage > 0 && !reachedsurface && currentpart != null) { var dinfo2 = new DamageInfo(failed ? DamageDefOf.Cut : DamageDefOf.SurgicalCut, partdamage, -1f, null, currentpart, null); pawn.TakeDamage(dinfo2); if (currentpart.depth == BodyPartDepth.Outside) { reachedsurface = true; } currentpart = currentpart.parent; } //Produce blood if (pawn.RaceProps.IsFlesh) { pawn.health.DropBloodFilth(); } //Produce waste chunks of meat (getting into Mad Max (2015) levels of squick here) except when removing solid parts (bones) int meatCount = (int)(part.def.hitPoints / 2.0f); if (meatCount > 0 && pawn.RaceProps.IsFlesh && pawn.RaceProps.meatDef != null && !part.def.IsSolid(part, pawn.health.hediffSet.hediffs)) { var meat = ThingMaker.MakeThing(pawn.RaceProps.meatDef, null); meat.stackCount = Verse.Rand.Range(Math.Max(meatCount / 2, 1), meatCount); GenPlace.TryPlaceThing(meat, pawn.Position, billDoer.Map, ThingPlaceMode.Near, null); } //Cause pain from the procedure var pain = LocalDefOf.JTFieldSurgeryPain; if (pain != null) { HealthUtility.AdjustSeverity(pawn, pain, maxDamage); var removed_parts = new List <BodyPartRecord> (); removed_parts.Add(part); //Increase pain based on every extremity also lost (phantom pain, so only by half) foreach (BodyPartRecord child in pawn.RaceProps.body.AllParts) { BodyPartRecord core = pawn.RaceProps.body.corePart; //I presume no guarantees that this list is serialised, so parts will all attempt to trace back to the // core to see if they can find any other removed parts along the way. BodyPartRecord tracetocore = child.parent; while (tracetocore != core && tracetocore is BodyPartRecord) { if (removed_parts.Contains(tracetocore)) { removed_parts.Add(child); HealthUtility.AdjustSeverity(pawn, pain, (float)part.def.hitPoints / 75f); break; } tracetocore = tracetocore.parent; } } } //Apply thoughts if (!pawn.RaceProps.Humanlike) { return; } if (pawn.Dead) { if (torture) //A particularly brutal execution { ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.GenericBrutal); if (billDoer.story.traits.HasTrait(TraitDefOf.Psychopath)) { Thought_Memory torturerSadist = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTortureSadist); if (torturerSadist != null) { billDoer.needs.mood.thoughts.memories.TryGainMemory(torturerSadist, pawn); } } else { Thought_Memory torturerNormal = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTorturer); if (torturerNormal != null) { billDoer.needs.mood.thoughts.memories.TryGainMemory(torturerNormal, pawn); } } } else //Emergency surgery //Each non-psychopathic colonist will feel bad that someone died because of their lack of preparation { var colonistDiedSurgery = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryColonistDiedSurgery); if (colonistDiedSurgery != null) { Map current_map = billDoer.Map; foreach (Pawn current in current_map.mapPawns.PawnsInFaction(billDoer.Faction)) { if (current != pawn && current.IsColonist && !current.story.traits.HasTrait(TraitDefOf.Psychopath)) { current.needs.mood.thoughts.memories.TryGainMemory(colonistDiedSurgery, pawn); } } } //Non-psychopathic doctors will feel bad if someone dies under the knife because they didn't use anaesthetic var killedFieldSurgery = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryKilledFieldSurgery); if (killedFieldSurgery != null && !billDoer.story.traits.HasTrait(TraitDefOf.Psychopath)) { billDoer.needs.mood.thoughts.memories.TryGainMemory(killedFieldSurgery, pawn); } } } else { //Always occurs: if tortured, upset about torture; if not tortured, upset about lack of anaesthetic var harmedMe = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDefOf.HarmedMe); pawn.needs.mood.thoughts.memories.TryGainMemory(harmedMe, billDoer); if (torture) { var tortureMasochist = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTortureMasochist); if (tortureMasochist != null && pawn.story.traits.HasTrait(LocalDefOf.M*******t) && pawn.story.traits.HasTrait(LocalDefOf.Prosthophile)) { pawn.needs.mood.thoughts.memories.TryGainMemory(tortureMasochist, billDoer); } else { var tortured = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTortureVictim); if (tortured != null) { pawn.needs.mood.thoughts.memories.TryGainMemory(tortured, billDoer); } } //Every colonist who is part of the colony is an accessory to torture var tortureWitness = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTortureWitness); if (tortureWitness != null) { foreach (Pawn current in pawn.Map.mapPawns.FreeColonists) { if (current != pawn && current.IsColonist && !current.story.traits.HasTrait(TraitDefOf.Psychopath) && !current.story.traits.HasTrait(TraitDefOf.Cannibal)) { current.needs.mood.thoughts.memories.TryGainMemory(tortureWitness, billDoer); } } } //The person committing the torture will feel good if psychopath or cannibal, bad if normal //New in version 4, this also applies to cannibals (as they have obtained some meat chunks) if (billDoer.story.traits.HasTrait(TraitDefOf.Psychopath) || billDoer.story.traits.HasTrait(TraitDefOf.Cannibal)) { var torturerSadist = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTortureSadist); if (torturerSadist != null) { billDoer.needs.mood.thoughts.memories.TryGainMemory(torturerSadist, pawn); } } else { var torturerNormal = (Thought_Memory)ThoughtMaker.MakeThought(LocalDefOf.JTFieldSurgeryTorturer); if (torturerNormal != null) { billDoer.needs.mood.thoughts.memories.TryGainMemory(torturerNormal, pawn); } } } } if (IsViolationOnPawn(pawn, part, Faction.OfPlayer)) { pawn.Faction.AffectGoodwillWith(billDoer.Faction, ViolationGoodwillImpact); } }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { pawn.health.AddHediff(this.recipe.addsHediff, part, null); ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, billDoer, PawnExecutionKind.GenericHumane); }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { pawn.Kill(null); ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, null, PawnExecutionKind.GenericHumane); }
// Token: 0x06001463 RID: 5219 RVA: 0x0009DD5C File Offset: 0x0009C15C public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { bool flag = MedicalRecipesUtility.IsClean(pawn, part); bool flag2 = this.IsViolationOnPawn(pawn, part, Faction.OfPlayer); if (billDoer != null) { if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] { billDoer, pawn }); if (PawnUtility.ShouldSendNotificationAbout(pawn) || PawnUtility.ShouldSendNotificationAbout(billDoer)) { string text; if (!this.recipe.successfullyRemovedHediffMessage.NullOrEmpty()) { text = string.Format(this.recipe.successfullyRemovedHediffMessage, billDoer.LabelShort, pawn.LabelShort); } else { text = "MessageSuccessfullyRemovedHediff".Translate(billDoer.LabelShort, pawn.LabelShort, this.recipe.removesHediff.label.Named("HEDIFF"), billDoer.Named("SURGEON"), pawn.Named("PATIENT")); } Messages.Message(text, pawn, MessageTypeDefOf.PositiveEvent, true); } } Hediff hediff = pawn.health.hediffSet.hediffs.Find((Hediff x) => x.def == this.recipe.removesHediff && x.Part == part); if (hediff != null) { pawn.health.RemoveHediff(hediff); DamageDef surgicalCut = DamageDefOf.SurgicalCut; float amount = 99999f; float armorPenetration = 999f; pawn.TakeDamage(new DamageInfo(surgicalCut, amount, armorPenetration, -1f, null, part, null, DamageInfo.SourceCategory.ThingOrUnknown, null)); if (flag) { if (pawn.Dead) { ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); } ThoughtUtility.GiveThoughtsForPawnOrganHarvested(pawn); } if (flag2 && pawn.Faction != null && billDoer != null && billDoer.Faction != null) { Faction faction = pawn.Faction; Faction faction2 = billDoer.Faction; int goodwillChange = -15; string reason = "GoodwillChangedReason_RemovedBodyPart".Translate(part.LabelShort); GlobalTargetInfo?lookTarget = new GlobalTargetInfo?(pawn); faction.TryAffectGoodwillWith(faction2, goodwillChange, true, true, reason, lookTarget); } } /* * bool flag = MedicalRecipesUtility.IsClean(pawn, part); * bool flag2 = this.IsViolationOnPawn(pawn, part, Faction.OfPlayer); * if (billDoer != null) * { * if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) * { * return; * } * TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] * { * billDoer, * pawn * }); * MedicalRecipesUtility.SpawnNaturalPartIfClean(pawn, part, billDoer.Position, billDoer.Map); * MedicalRecipesUtility.SpawnThingsFromHediffs(pawn, part, billDoer.Position, billDoer.Map); * } * DamageDef surgicalCut = DamageDefOf.SurgicalCut; * float amount = 99999f; * float armorPenetration = 999f; * pawn.TakeDamage(new DamageInfo(surgicalCut, amount, armorPenetration, -1f, null, part, null, DamageInfo.SourceCategory.ThingOrUnknown, null)); * if (flag) * { * if (pawn.Dead) * { * ThoughtUtility.GiveThoughtsForPawnExecuted(pawn, PawnExecutionKind.OrganHarvesting); * } * ThoughtUtility.GiveThoughtsForPawnOrganHarvested(pawn); * } * if (flag2 && pawn.Faction != null && billDoer != null && billDoer.Faction != null) * { * Faction faction = pawn.Faction; * Faction faction2 = billDoer.Faction; * int goodwillChange = -15; * string reason = "GoodwillChangedReason_RemovedBodyPart".Translate(part.LabelShort); * GlobalTargetInfo? lookTarget = new GlobalTargetInfo?(pawn); * faction.TryAffectGoodwillWith(faction2, goodwillChange, true, true, reason, lookTarget); * } */ }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(iPrisoner); this.FailOnDestroyedOrNull(iSacrificeBuilding); this.FailOnAggroMentalState(iPrisoner); yield return(Toils_Goto.GotoThing(iPrisoner, PathEndMode.OnCell)); yield return(Toils_Haul.StartCarryThing(iPrisoner, true, false)); yield return(Toils_Goto.GotoThing(iSacrificeBuilding, SacrificeSpot.InteractionCell)); yield return(Toils_Reserve.Release(iPrisoner)); var doSacrificePrisoner = new Toil { socialMode = RandomSocialMode.Off, }; doSacrificePrisoner.initAction = () => { Sacrificer.carryTracker.TryDropCarriedThing(SacrificeSpot.InteractionCell, ThingPlaceMode.Direct, out var thing, null); Prisoner.jobs.StartJob(JobMaker.MakeJob(Defs.PrisonerWait)); }; doSacrificePrisoner.AddFailCondition(() => Prisoner.Dead); doSacrificePrisoner.defaultCompleteMode = ToilCompleteMode.Never; doSacrificePrisoner.AddPreTickAction(() => { --TicksLeft; if (TicksLeft <= 0) { ReadyForNextToil(); } }); yield return(doSacrificePrisoner.WithProgressBar(iPawn, () => (TicksMax - (float)TicksLeft) / TicksMax)); var afterSacrificePrisoner = new Toil { defaultCompleteMode = ToilCompleteMode.Instant, initAction = () => { var heartBpr = Prisoner.RaceProps.body.AllParts.Find(bpr => bpr.def.defName == "Heart"); var dInfo = new DamageInfo(Defs.HeartExtraction, 99999f, armorPenetration: 999f, hitPart: heartBpr); Prisoner.Kill(dInfo); ThoughtUtility.GiveThoughtsForPawnExecuted(Prisoner, Sacrificer, PawnExecutionKind.GenericBrutal); // Apply negative relations modifier. if (pawn.Faction != null && Prisoner.Faction != null) { Faction playerFaction = pawn.Faction; Faction prisonerFaction = Prisoner.Faction; string reason = "GoodwillChangedReason_RemovedBodyPart".Translate(heartBpr.Label); GlobalTargetInfo?LookTargets = pawn; playerFaction.TryAffectGoodwillWith(prisonerFaction, -25); } // Apply thoughts to pawns. foreach (var mapPawn in Map.mapPawns.FreeColonistsAndPrisoners) { if (mapPawn.IsPrisoner) { mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedFear); } else if (mapPawn.IsColonist && (mapPawn.IsRevia() || mapPawn.IsSkarnite())) { mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedPositive); } else if (mapPawn.IsColonist && !(mapPawn.IsCannibal() || mapPawn.IsPsychopath() || mapPawn.IsBloodlust())) { mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedNegative); } } // Spawn the product, or handle one of the other effects. // Find a good spot to spawn the product. IntVec3 spawnPos = CellFinder.FindNoWipeSpawnLocNear( Prisoner.Position, Map, Defs.Bloodstone, Rot4.Random, 6, pos => { return ((pos.x < Prisoner.Position.x - 1 || pos.x > Prisoner.Position.x + 1) && // F**k you Tynan. Learn your coordinates! (pos.z < Prisoner.Position.z - 1 || pos.z > Prisoner.Position.z + 1)); }); if (Map.GameConditionManager.ConditionIsActive(Defs.Eclipse)) { var missingParts = pawn.health.hediffSet.GetMissingPartsCommonAncestors(); if (missingParts.Count > 0) { var missing = missingParts.RandomElement(); pawn.health.hediffSet.hediffs.Remove(missing); var maxHp = missing.Part.def.GetMaxHealth(pawn); var injuryHediff = pawn.health.AddHediff(HediffDefOf.Cut, missing.Part, new DamageInfo(DamageDefOf.Rotting, 1.0f, 10000.00f)); var permHediffComp = injuryHediff.TryGetComp <HediffComp_GetsPermanent>(); injuryHediff.Severity = maxHp / 2.0f; permHediffComp.IsPermanent = true; } else { var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map); thing.stackCount += 2; } } else if (Map.GameConditionManager.ConditionIsActive(Defs.SolarFlare)) { var permInjuries = pawn.health.hediffSet.hediffs.Where(h => h.IsPermanent() && !(h is Hediff_MissingPart)).ToList(); if (permInjuries.Count > 0) { var randomInjury = permInjuries.RandomElement(); randomInjury.Severity -= randomInjury.Part.depth == BodyPartDepth.Inside ? 2.0f : 4.0f; } else { var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map); thing.stackCount += 1; } } else { var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map); } var bloodthirst = Sacrificer.needs.TryGetNeed <BloodthirstNeed>(); if (bloodthirst != null) { bloodthirst.CurLevel += 0.80f * Prisoner.BodySize; } TaleRecorder.RecordTale(Defs.TaleSacrificed, new[] { Sacrificer, Prisoner }); // Find a good spot to move the prisoner corpse. IntVec3 movePos = CellFinder.FindNoWipeSpawnLocNear( Prisoner.Position, Map, Prisoner.Corpse.def, Rot4.Random, 6, pos => { return ((pos.x < Prisoner.Position.x - 1 || pos.x > Prisoner.Position.x + 1) && // F**k you Tynan. Learn your coordinates! (pos.z < Prisoner.Position.z - 1 || pos.z > Prisoner.Position.z + 1)); }); Prisoner.Corpse.Position = movePos; } }; yield return(afterSacrificePrisoner); }