Beispiel #1
0
        private void TalkToDoll()
        {
            var symbol = InteractionDefOf.Chitchat.GetSymbol();

            if (Rand.Value > 0.5f && pawn?.needs?.joy?.CurCategory <= JoyCategory.Low ||
                (pawn?.story?.traits.HasTrait(TraitDefOf.Abrasive) ?? false))
            {
                symbol = InteractionDefOf.Insult.GetSymbol();
            }

            MoteMaker.MakeInteractionBubble(pawn, null, ThingDefOf.Mote_Speech, symbol);
//            float extraLuckFromQuality = base.TargetThingA.GetStatValue(StatDefOf.JoyGainFactor, true);
//            float extraLuckFromSmarts = pawn.skills.GetSkill(SkillDefOf.Intellectual).levelInt;
//
//            float yourLuckyNumber = ((1f + extraLuckFromSmarts) * extraLuckFromQuality) / 100;
//
//            Log.Message("lucky number is: " + yourLuckyNumber.ToString());
//
//            if (Rand.Chance(yourLuckyNumber) || DebugSettings.godMode)
//            {
//                Thing reward = ThingMaker.MakeThing(ThingDefOf.Gold);
//                reward.stackCount = Rand.RangeInclusive(10, 50);
//                GenSpawn.Spawn(reward, pawn.Position, pawn.Map);
//                PuzzleBox.Destroy();
//                Letter letter = LetterMaker.MakeLetter("LotRD_PuzzleSolvedLabel".Translate(), "LotRD_PuzzleSolved".Translate(new object[] {
//                    pawn.Label,
//                    reward.Label,
//                }), LetterDefOf.PositiveEvent);
//                Find.LetterStack.ReceiveLetter(letter);
//            }
        }
Beispiel #2
0
 private static void TryCreateBubble(Pawn pawn1, Pawn pawn2, Texture2D symbol)
 {
     if (pawn1.interactions.InteractedTooRecentlyToInteract())
     {
         return;
     }
     MoteMaker.MakeInteractionBubble(pawn1, pawn2, ThingDefOf.Mote_Speech, symbol);
 }
Beispiel #3
0
        protected Toil Interact(Pawn talkee, InteractionDef intDef, int duration)
        {
            var toil = new Toil {
                initAction = () => {
                    PawnUtility.ForceWait(talkee, duration, pawn);
                    TargetThingB = pawn;
                    MoteMaker.MakeInteractionBubble(pawn, talkee, intDef.interactionMote, intDef.Symbol);
                },
                socialMode          = RandomSocialMode.Normal,
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = duration
            };

            return(toil.WithProgressBarToilDelay(TargetIndex.B));
        }
Beispiel #4
0
 // Token: 0x06000016 RID: 22 RVA: 0x000023AC File Offset: 0x000005AC
 private Toil InteractToil()
 {
     return(Toils_General.Do(delegate
     {
         System.Random rnd = new System.Random();
         int rand = rnd.Next(0, 2);
         bool flag = rand == 0;
         Pawn _p;
         if (flag)
         {
             _p = ((Building_Bell)this.pawn.mindState.duty.focus.Thing).fighter1.p;
         }
         else
         {
             _p = ((Building_Bell)this.pawn.mindState.duty.focus.Thing).fighter2.p;
         }
         RenderTexture head = PortraitsCache.Get(_p, ColonistBarColonistDrawer.PawnTextureSize, default(Vector3), 1f);
         Texture2D headIcon = new Texture2D(75, 75);
         for (int i = 0; i < 75; i++)
         {
             for (int j = 0; j < 75; j++)
             {
                 headIcon.SetPixel(i, j, Color.clear);
             }
         }
         RenderTexture.active = head;
         headIcon.ReadPixels(new Rect(-10f, 0f, 50f, (float)head.height), 0, 0);
         headIcon.Apply();
         Texture2D cheerIcon = InteractionDefOfArena.Cheer.Symbol;
         RenderTexture tmp = RenderTexture.GetTemporary(cheerIcon.width, cheerIcon.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Default, 1);
         Graphics.Blit(cheerIcon, tmp);
         RenderTexture previous = RenderTexture.active;
         RenderTexture.active = tmp;
         Texture2D _cheerIcon = new Texture2D(cheerIcon.width, cheerIcon.height);
         _cheerIcon.ReadPixels(new Rect(0f, 0f, (float)tmp.width, (float)tmp.height), 0, 0);
         _cheerIcon.Apply();
         RenderTexture.active = previous;
         RenderTexture.ReleaseTemporary(tmp);
         Texture2D merged = JobDriver_CheerForFighter.MergeTextures(_cheerIcon, headIcon);
         MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, merged);
     }));
 }
        public static void TryWorshipInteraction(Pawn preacher, Pawn recipient, InteractionDef intDef)
        {
            if (preacher == recipient)
            {
                Log.Warning(preacher + " tried to interact with self, interaction=" + intDef.defName);
                return;
            }

            //if (!tracker.CanInteractNowWith(recipient))
            //    return false;
            var extraSentencePacks = new List <RulePackDef>();
            //if (intDef.initiatorThought != null)
            //    Pawn_InteractionsTracker.AddInteractionThought(preacher, recipient, intDef.initiatorThought);
            //if (intDef.recipientThought != null && recipient.needs.mood != null)
            //    Pawn_InteractionsTracker.AddInteractionThought(recipient, preacher, intDef.recipientThought);
            //if (intDef.initiatorXpGainSkill != null)
            //    preacher.skills.Learn(intDef.initiatorXpGainSkill, (float)intDef.initiatorXpGainAmount, false);
            //if (intDef.recipientXpGainSkill != null && recipient.RaceProps.Humanlike)
            //    recipient.skills.Learn(intDef.recipientXpGainSkill, (float)intDef.recipientXpGainAmount, false);
            var flag = false;

            if (recipient.RaceProps.Humanlike)
            {
                flag = recipient.interactions.CheckSocialFightStart(intDef, preacher);
            }

            if (!flag)
            {
                intDef.Worker.Interacted(preacher, recipient, extraSentencePacks, out _, out _, out _, out _);
            }

            MoteMaker.MakeInteractionBubble(preacher, recipient, intDef.interactionMote, intDef.Symbol);
            if (flag)
            {
                extraSentencePacks.Add(RulePackDefOf.Sentence_SocialFightStarted);
            }

            var entryInteraction = new PlayLogEntry_Interaction(intDef, preacher, recipient, extraSentencePacks);

            Find.PlayLog.Add(entryInteraction);
        }
Beispiel #6
0
        private void DoEffect()
        {
            BloodVictim.TransferBloodTo(1, BloodFeeder, false);
            if (!Victim.InAggroMentalState)
            {
                Victim.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.Berserk, "ROMV_AttemptedDiablerie".Translate(this.pawn.Named("PAWN")), false, false, null);
            }

            if (DiablerieInteractionGiven)
            {
                return;
            }
            DiablerieInteractionGiven = true;
            Find.LetterStack.ReceiveLetter("ROMV_AttemptedDiablerie".Translate(this.pawn.Named("PAWN")), "ROMV_VampireDiablerieAttemptedLetter".Translate(this.pawn.Named("PAWN"), Victim.Named("VICTIM")), LetterDefOf.ThreatSmall, pawn);
            MoteMaker.MakeInteractionBubble(GetActor(), Victim, VampDefOf.ROMV_VampireDiablerieAttempt.interactionMote, VampDefOf.ROMV_VampireDiablerieAttempt.Symbol);
            if (this?.Victim?.needs?.mood?.thoughts?.memories is MemoryThoughtHandler m)
            {
                m.TryGainMemory(VampDefOf.ROMV_VampireDiablerieAttempt.recipientThought, GetActor());
            }
            Find.PlayLog.Add(new PlayLogEntry_Interaction(VampDefOf.ROMV_VampireDiablerieAttempt, this.GetActor(), this.Victim, null));
        }
 public override void Tick()
 {
     base.Tick();
     if (this.realPawn == null)
     {
         this.realPawn = this.pawn as PsychologyPawn;
     }
     if (this.otherPawn == null)
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (!this.otherPawn.Spawned || !this.pawn.Spawned || !InteractionUtility.CanReceiveInteraction(this.pawn) || !InteractionUtility.CanReceiveInteraction(this.otherPawn))
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if ((this.pawn.Position - this.otherPawn.Position).LengthHorizontalSquared >= 54f || !GenSight.LineOfSight(this.pawn.Position, this.otherPawn.Position, this.pawn.Map, true))
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (this.otherPawn.Dead || this.otherPawn.Downed || this.otherPawn.InAggroMentalState)
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (this.pawn.IsHashIntervalTick(200))
     {
         if (Rand.Value > 1f - (this.ageTicks / 400000f))
         {
             this.pawn.health.RemoveHediff(this);
             return;
         }
         else if (Rand.Value < 0.2f && this.pawn.Map != null)
         {
             MoteMaker.MakeInteractionBubble(this.pawn, otherPawn, InteractionDefOf.DeepTalk.interactionMote, InteractionDefOf.DeepTalk.Symbol);
         }
     }
 }
        private void DoEffect()
        {
            BloodVictim.TransferBloodTo(1, BloodFeeder, false);
            if (!Victim.InAggroMentalState)
            {
                Victim.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.Berserk, "ROMV_AttemptedDiablerie".Translate(this.pawn), false, false, null);
//                Victim.mindState.mentalStateHandler.TryStartMentalState(VampDefOf.MurderousRage,
//                    "ROMV_AttemptedDiablerie".Translate(), false, false, GetActor());
            }

            if (DiablerieInteractionGiven)
            {
                return;
            }
            DiablerieInteractionGiven = true;
            MoteMaker.MakeInteractionBubble(GetActor(), Victim, VampDefOf.ROMV_VampireDiablerieAttempt.interactionMote, VampDefOf.ROMV_VampireDiablerieAttempt.Symbol);
            if (this?.Victim?.needs?.mood?.thoughts?.memories is MemoryThoughtHandler m)
            {
                m.TryGainMemory(VampDefOf.ROMV_VampireDiablerieAttempt.recipientThought, GetActor());
            }
            Find.PlayLog.Add(new PlayLogEntry_Interaction(VampDefOf.ROMV_VampireDiablerieAttempt, this.GetActor(), this.Victim, null));
        }
        public override void LordToilTick()
        {
            base.LordToilTick();
            LordJob_VisitMayor meeting = this.lord.LordJob as LordJob_VisitMayor;

            for (int i = 0; i < this.lord.ownedPawns.Count; i++)
            {
                if (this.lord.ownedPawns[i].Position == null || this.spot == null || this.lord.ownedPawns[i].Map == null || !PartyUtility.InPartyArea(this.lord.ownedPawns[i].Position, this.spot, this.lord.ownedPawns[i].Map))
                {
                    return;
                }
            }
            if (meeting != null)
            {
                meeting.ticksInSameRoom += 1;
                if (meeting.ticksInSameRoom % 200 == 0 && Rand.Value < 0.2f)
                {
                    meeting.mayor.skills.Learn(SkillDefOf.Social, 0.5f);
                    MoteMaker.MakeInteractionBubble(meeting.constituent, meeting.mayor, InteractionDefOf.DeepTalk.interactionMote, InteractionDefOf.DeepTalk.Symbol);
                }
            }
        }
        public override void PostRemoved()
        {
            base.PostRemoved();
            if (this.realPawn == null)
            {
                this.realPawn = this.pawn as PsychologyPawn;
            }
            if (this.realPawn != null && this.otherPawn != null)
            {
                Hediff otherConvo = otherPawn.health.hediffSet.hediffs.Find(h => h is Hediff_Conversation && ((Hediff_Conversation)h).otherPawn == this.realPawn);
                if (otherConvo != null)
                {
                    this.otherPawn.health.RemoveHediff(otherConvo);
                }
                string talkDesc;
                if (this.ageTicks < 500)
                {
                    int numShortTalks = int.Parse("NumberOfShortTalks".Translate());
                    talkDesc = "ShortTalk" + Rand.RangeInclusive(1, numShortTalks);
                }
                else if (this.ageTicks < 1500)
                {
                    int numNormalTalks = int.Parse("NumberOfNormalTalks".Translate());
                    talkDesc = "NormalTalk" + Rand.RangeInclusive(1, numNormalTalks);
                }
                else if (this.ageTicks < 5000)
                {
                    int numLongTalks = int.Parse("NumberOfLongTalks".Translate());
                    talkDesc = "LongTalk" + Rand.RangeInclusive(1, numLongTalks);
                }
                else
                {
                    int numEpicTalks = int.Parse("NumberOfEpicTalks".Translate());
                    talkDesc = "EpicTalk" + Rand.RangeInclusive(1, numEpicTalks);
                }
                //We create a dynamic def to hold this thought so that the game won't worry about it being used anywhere else.
                ThoughtDef def = new ThoughtDef();
                def.defName          = this.pawn.GetHashCode() + "Conversation" + topic.defName;
                def.label            = topic.defName;
                def.durationDays     = 60f;
                def.nullifyingTraits = new List <TraitDef>();
                def.nullifyingTraits.Add(TraitDefOf.Psychopath);
                def.thoughtClass = typeof(Thought_MemorySocialDynamic);
                ThoughtStage stage = new ThoughtStage();
                //Base opinion mod is 5 to the power of controversiality.
                float opinionMod = Mathf.Pow(5f, topic.controversiality);
                //Multiplied by difference between their personality ratings, on an exponential scale.
                opinionMod *= Mathf.Lerp(-1.25f, 1.25f, Mathf.Pow(1f - Mathf.Abs(this.realPawn.psyche.GetPersonalityRating(topic) - this.otherPawn.psyche.GetPersonalityRating(topic)), 3));
                //Cool pawns are liked more.
                opinionMod += Mathf.Pow(2f, topic.controversiality) * (0.5f - this.otherPawn.psyche.GetPersonalityRating(PersonalityNodeDefOf.Cool));
                //The length of the talk has a large impact on how much the pawn cares.
                opinionMod *= 5f * (this.ageTicks / (GenDate.TicksPerHour * 2.25f)); //talkModifier[talkLength]
                //If they had a bad experience, the more polite the pawn is, the less they're bothered by it.
                opinionMod *= (opinionMod < 0f ? 0.5f + (1f - this.otherPawn.psyche.GetPersonalityRating(PersonalityNodeDefOf.Polite)) : 1f);
                //The more judgmental the pawn, the more they're affected by all conversations.
                opinionMod *= 0.5f + this.realPawn.psyche.GetPersonalityRating(PersonalityNodeDefOf.Judgmental);
                if (opinionMod < 0f)
                {
                    opinionMod *= PopulationModifier;
                }
                stage.label             = "ConversationStage".Translate() + " " + topic.conversationTopic;
                stage.baseOpinionOffset = Mathf.RoundToInt(opinionMod);
                def.stages.Add(stage);

                /* The more they know about someone, the less likely small thoughts are to have an impact on their opinion.
                 * This helps declutter the Social card without preventing pawns from having conversations.
                 * They just won't change their mind about the colonist as a result.
                 */
                if (Rand.Value < Mathf.InverseLerp(0f, this.realPawn.psyche.TotalThoughtOpinion(this.otherPawn), 250f + Mathf.Abs(stage.baseOpinionOffset)) && stage.baseOpinionOffset != 0)
                {
                    this.pawn.needs.mood.thoughts.memories.TryGainMemory(def, this.otherPawn);
                }
                if (this.waveGoodbye && this.pawn.Map != null)
                {
                    InteractionDef endConversation = new InteractionDef();
                    endConversation.defName = "EndConversation";
                    RulePack      goodbyeText = new RulePack();
                    FieldInfo     RuleStrings = typeof(RulePack).GetField("rulesStrings", BindingFlags.Instance | BindingFlags.NonPublic);
                    List <string> text        = new List <string>(1);
                    text.Add("logentry->" + talkDesc.Translate(topic.conversationTopic));
                    RuleStrings.SetValue(goodbyeText, text);
                    endConversation.logRulesInitiator = goodbyeText;
                    endConversation.logRulesRecipient = goodbyeText;
                    FieldInfo Symbol = typeof(InteractionDef).GetField("symbol", BindingFlags.Instance | BindingFlags.NonPublic);
                    Symbol.SetValue(endConversation, Symbol.GetValue(InteractionDefOf.DeepTalk));
                    PlayLogEntry_InteractionConversation log = new PlayLogEntry_InteractionConversation(endConversation, realPawn, this.otherPawn, new List <RulePackDef>());
                    Find.PlayLog.Add(log);
                    MoteMaker.MakeInteractionBubble(this.pawn, this.otherPawn, InteractionDefOf.Chitchat.interactionMote, InteractionDefOf.Chitchat.Symbol);
                }
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Commence fail checks!

            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.B);
            this.FailOnAggroMentalState(TargetIndex.A);

            yield return(Toils_Reserve.Reserve(TakeeIndex));

            yield return(Toils_Reserve.Reserve(AltarIndex, Building_SacrificialAltar.LyingSlotsCount));

            yield return(new Toil
            {
                initAction = delegate
                {
                    DropAltar.ChangeState(Building_SacrificialAltar.State.sacrificing,
                                          Building_SacrificialAltar.SacrificeState.gathering);
                }
            });

            //Toil 1: Go to prisoner.
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch)
                         .FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B)
                         .FailOn(() => job.def == JobDefOf.Arrest && !Takee.CanBeArrestedBy(pawn))
                         .FailOn(() =>
                                 !pawn.CanReach(DropAltar, PathEndMode.OnCell, Danger.Deadly))
                         .FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(new Toil
            {
                initAction = delegate
                {
                    if (!job.def.makeTargetPrisoner)
                    {
                        return;
                    }

                    var targetAThing = (Pawn)job.targetA.Thing;
                    var lord = targetAThing.GetLord();
                    lord?.Notify_PawnAttemptArrested(targetAThing);

                    GenClamor.DoClamor(targetAThing, 10f, ClamorDefOf.Harm);
                    if (job.def == JobDefOf.Arrest && !targetAThing.CheckAcceptArrest(pawn))
                    {
                        pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                    }
                }
            });

            //Toil 2: Carry prisoner.
            yield return(Toils_Haul.StartCarryThing(TargetIndex.A));

            //Toil 3: Go to the altar.
            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.InteractionCell));

            //Toil 4: Release the prisoner.
            yield return(Toils_Reserve.Release(TargetIndex.B));

            //Toil 5: Restrain the prisoner.
            yield return(new Toil
            {
                initAction = delegate
                {
                    //In-case this fails...
                    var position = DropAltar.Position;
                    pawn.carryTracker.TryDropCarriedThing(position, ThingPlaceMode.Direct, out _);
                    if (DropAltar.Destroyed || !DropAltar.AnyUnoccupiedLyingSlot)
                    {
                        return;
                    }

                    Takee.Position = DropAltar.GetLyingSlotPos();
                    Takee.Notify_Teleported(false);
                    Takee.stances.CancelBusyStanceHard();
                    var newJob = new Job(CultsDefOf.Cults_WaitTiedDown, DropAltar);
                    Takee.jobs.StartJob(newJob);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            //Toil 6: Time to chant ominously
            var chantingTime = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = CultUtility.ritualDuration
            };

            chantingTime.WithProgressBarToilDelay(TargetIndex.A);
            chantingTime.PlaySustainerOrSound(CultsDefOf.RitualChanting);
            var deitySymbol = ((CosmicEntityDef)DropAltar.SacrificeData.Entity.def).Symbol;

            chantingTime.initAction = delegate
            {
                if (deitySymbol != null)
                {
                    MoteMaker.MakeInteractionBubble(pawn, null, ThingDefOf.Mote_Speech, deitySymbol);
                }


                //STATE - SACRIFICING
                DropAltar.ChangeState(Building_SacrificialAltar.State.sacrificing,
                                      Building_SacrificialAltar.SacrificeState.sacrificing);
            };

            yield return(chantingTime);

            //Toil 8: Execution of Prisoner
            yield return(new Toil
            {
                initAction = delegate
                {
                    //BodyPartDamageInfo value = new BodyPartDamageInfo(this.Takee.health.hediffSet.GetBrain(), false, quiet);
                    Takee.TakeDamage(new DamageInfo(DamageDefOf.ExecutionCut, 99999, 0f, -1f, pawn,
                                                    Utility.GetHeart(Takee.health.hediffSet)));
                    if (!Takee.Dead)
                    {
                        Takee.Kill(null);
                    }

                    //ThoughtUtility.GiveThoughtsForPawnExecuted(this.Takee, PawnExecutionKind.GenericHumane);
                    TaleRecorder.RecordTale(TaleDefOf.ExecutedPrisoner, pawn, Takee);
                    CultUtility.SacrificeExecutionComplete(DropAltar);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            AddFinishAction(() =>
            {
                //It's a day to remember
                var taleToAdd = TaleDef.Named("HeldSermon");
                if ((pawn.IsColonist || pawn.IsSlaveOfColony || pawn.HostFaction == Faction.OfPlayer) && taleToAdd != null)
                {
                    TaleRecorder.RecordTale(taleToAdd, pawn);
                }

                //When the ritual is finished -- then let's give the thoughts

                /*
                 * if (DropAltar.currentSacrificeState == Building_SacrificialAltar.SacrificeState.finished)
                 * {
                 *  if (this.pawn == null) return;
                 *  if (DropAltar.sacrifice != null)
                 *  {
                 *      CultUtility.AttendSacrificeTickCheckEnd(this.pawn, DropAltar.sacrifice, true);
                 *  }
                 *  else
                 *  {
                 *      CultUtility.AttendSacrificeTickCheckEnd(this.pawn, null);
                 *  }
                 * }
                 */
            });
        }
 private void Finished()
 {
     if (PsycheHelper.PsychologyEnabled(mayor) && PsycheHelper.PsychologyEnabled(constituent))
     {
         if (this.ticksInSameRoom > 0)
         {
             if (this.complaint)
             {
                 ThoughtDef complaintDef = new ThoughtDef();
                 complaintDef.label        = "MayorComplaint";
                 complaintDef.durationDays = 1f + 4f * this.mayor.GetStatValue(StatDefOf.SocialImpact);
                 //Constituent thought duration affected by mayor's Social stat
                 complaintDef.thoughtClass            = typeof(Thought_MemoryDynamic);
                 complaintDef.stackedEffectMultiplier = 1f;
                 complaintDef.stackLimit = 999;
                 ThoughtStage complaintStage = new ThoughtStage();
                 float        complaintMood  = 18f * (PsycheHelper.Comp(mayor).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Empathetic) - 0.33f);
                 //Base complaint mood determined by mayor's Empathetic trait
                 complaintMood *= (float)this.ticksInSameRoom / (float)GenDate.TicksPerHour;
                 //Length of meeting also affects mood
                 complaintMood *= (complaintMood < 0f ? Mathf.Lerp(1.25f, 0.75f, PsycheHelper.Comp(constituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Polite)) : 1f);
                 //Negative meeting thoughts (unempathetic mayors) mitigated by mayor's politeness
                 complaintMood += (BeautyUtility.AverageBeautyPerceptible(this.constituent.Position, this.constituent.Map) / 10f);
                 //Beauty of the room has a net positive effect on the thought
                 complaintMood *= 0.75f + (PsycheHelper.Comp(constituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Judgmental) / 2f);
                 //Constituent's Judgmental trait changes how much the thought affects them
                 complaintStage.label          = "ComplaintLabel".Translate();
                 complaintStage.description    = "ComplaintDesc".Translate();
                 complaintStage.baseMoodEffect = Mathf.RoundToInt(complaintMood);
                 complaintDef.defName          = this.constituent.GetHashCode() + "MayorComplaint" + complaintStage.baseMoodEffect;
                 complaintDef.stages.Add(complaintStage);
                 if (complaintStage.baseMoodEffect != 0)
                 {
                     this.constituent.needs.mood.thoughts.memories.TryGainMemory(complaintDef, this.mayor);
                 }
             }
             ThoughtDef visitDef = new ThoughtDef();
             visitDef.label        = "MayorVisited";
             visitDef.durationDays = 0.75f + 2f * (1f - PsycheHelper.Comp(mayor).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent));
             //Mayor thought duration affected by mayor's Independent trait
             visitDef.thoughtClass            = typeof(Thought_MemoryDynamic);
             visitDef.stackedEffectMultiplier = 1f;
             visitDef.stackLimit = 999;
             ThoughtStage stage = new ThoughtStage();
             float        mood  = 7f * (complaint ? -0.5f - (1f - this.constituent.needs.mood.CurLevel) : 0.1f + (this.constituent.needs.mood.CurLevel * 0.65f));
             //Base visit mood determined by the mood level of the constituent
             mood *= (float)this.ticksInSameRoom / (float)GenDate.TicksPerHour;
             //Length of meeting also affects mood
             mood *= (mood < 0f ? Mathf.Lerp(1.25f, 0.75f, PsycheHelper.Comp(constituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Polite)) : 1f);
             //Negative meeting thoughts (unhappy constituents) mitigated by constituent's politeness
             mood *= 0.5f + (1f - PsycheHelper.Comp(this.mayor).Psyche.GetPersonalityRating(PersonalityNodeDefOf.LaidBack));
             //Mayor's Laid-Back trait strongly impacts how much the thought affects them
             stage.label          = "VisitLabel".Translate();
             stage.description    = "VisitDesc".Translate();
             stage.baseMoodEffect = Mathf.RoundToInt(mood);
             visitDef.defName     = this.mayor.GetHashCode() + "MayorVisited" + stage.baseMoodEffect;
             visitDef.stages.Add(stage);
             if (stage.baseMoodEffect != 0)
             {
                 this.mayor.needs.mood.thoughts.memories.TryGainMemory(visitDef, this.constituent);
             }
             InteractionDef endConversation = new InteractionDef();
             endConversation.defName = "EndConversation";
             FieldInfo     RuleStrings     = typeof(RulePack).GetField("rulesStrings", BindingFlags.Instance | BindingFlags.NonPublic);
             RulePack      goodbyeTextInit = new RulePack();
             List <string> text            = new List <string>(1);
             if (complaint)
             {
                 text.Add("r_logentry->" + "Complained".Translate());
             }
             else
             {
                 text.Add("r_logentry->" + "Supported".Translate());
             }
             RuleStrings.SetValue(goodbyeTextInit, text);
             endConversation.logRulesInitiator = goodbyeTextInit;
             FieldInfo Symbol = typeof(InteractionDef).GetField("symbol", BindingFlags.Instance | BindingFlags.NonPublic);
             Symbol.SetValue(endConversation, Symbol.GetValue(InteractionDefOfPsychology.HangOut));
             PlayLogEntry_InteractionConversation log = new PlayLogEntry_InteractionConversation(endConversation, this.constituent, this.mayor, new List <RulePackDef>());
             Find.PlayLog.Add(log);
             MoteMaker.MakeInteractionBubble(this.mayor, this.constituent, InteractionDefOf.Chitchat.interactionMote, InteractionDefOf.Chitchat.Symbol);
         }
     }
 }
Beispiel #13
0
        public static string InteractWith(Pawn pawn, Pawn recipient, InteractionDef interaction)
        {
            if (pawn == recipient)
            {
                return(null);
            }

            var extraSentencePacks = new List <RulePackDef>();

            if (interaction.initiatorThought != null)
            {
                Pawn_InteractionsTracker.AddInteractionThought(pawn, recipient, interaction.initiatorThought);
            }

            if (interaction.recipientThought != null && recipient.needs.mood != null)
            {
                Pawn_InteractionsTracker.AddInteractionThought(recipient, pawn, interaction.recipientThought);
            }

            bool isSocialFight = recipient.RaceProps.Humanlike && recipient.interactions.CheckSocialFightStart(interaction, pawn);

            string      letterText  = null;
            string      letterLabel = null;
            LetterDef   letterDef   = null;
            LookTargets lookTargets = null;

            if (!isSocialFight)
            {
                interaction.Worker.Interacted(pawn, recipient, extraSentencePacks, out letterText, out letterLabel, out letterDef, out lookTargets);
            }

            MoteMaker.MakeInteractionBubble(
                pawn,
                recipient,
                interaction.interactionMote,
                interaction.GetSymbol(pawn.Faction, pawn.Ideo),
                interaction.GetSymbolColor(pawn.Faction)
                );

            if (isSocialFight)
            {
                extraSentencePacks.Add(RulePackDefOf.Sentence_SocialFightStarted);
            }

            var entry = new PlayLogEntry_Interaction(interaction, pawn, recipient, extraSentencePacks);

            Find.PlayLog.Add(entry);

            string text = RichTextHelper.StripTags(entry.ToGameStringFromPOV(pawn));

            if (letterDef == null)
            {
                return(MakeFirstPerson(pawn.LabelShort, text));
            }

            if (!letterText.NullOrEmpty())
            {
                text = text + "\n\n" + RichTextHelper.StripTags(letterText);
            }

            Find.LetterStack.ReceiveLetter(letterLabel, text, letterDef, lookTargets ?? pawn);

            return(MakeFirstPerson(pawn.LabelShort, text.Replace("\n\n", " ")));
        }
Beispiel #14
0
 public override void PostRemoved()
 {
     base.PostRemoved();
     if (this.pawn != null && this.otherPawn != null)
     {
         if (this.pawn.Dead || this.otherPawn.Dead || !PsycheHelper.PsychologyEnabled(pawn) || !PsycheHelper.PsychologyEnabled(otherPawn))
         {
             return;
         }
         Hediff_Conversation otherConvo = otherPawn.health.hediffSet.hediffs.Find(h => h is Hediff_Conversation && ((Hediff_Conversation)h).otherPawn == this.pawn) as Hediff_Conversation;
         if (otherConvo != null)
         {
             this.otherPawn.health.RemoveHediff(otherConvo);
             this.startedFight = otherConvo.startedFight;
         }
         string talkDesc;
         if (this.ageTicks < 500)
         {
             int numShortTalks = int.Parse("NumberOfShortTalks".Translate());
             talkDesc = "ShortTalk" + Rand.RangeInclusive(1, numShortTalks);
         }
         else if (this.ageTicks < GenDate.TicksPerHour / 2)
         {
             int numNormalTalks = int.Parse("NumberOfNormalTalks".Translate());
             talkDesc = "NormalTalk" + Rand.RangeInclusive(1, numNormalTalks);
         }
         else if (this.ageTicks < GenDate.TicksPerHour * 2.5)
         {
             int numLongTalks = int.Parse("NumberOfLongTalks".Translate());
             talkDesc = "LongTalk" + Rand.RangeInclusive(1, numLongTalks);
         }
         else
         {
             int numEpicTalks = int.Parse("NumberOfEpicTalks".Translate());
             talkDesc = "EpicTalk" + Rand.RangeInclusive(1, numEpicTalks);
         }
         float          opinionMod;
         ThoughtDef     def             = CreateSocialThought(out opinionMod);
         bool           mattered        = TryGainThought(def, Mathf.RoundToInt(opinionMod));
         InteractionDef endConversation = new InteractionDef();
         endConversation.socialFightBaseChance = 0.2f * PsycheHelper.Comp(pawn).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive) * PopulationModifier * Mathf.InverseLerp(0f, -80f, opinionMod);
         endConversation.defName = "EndConversation";
         endConversation.label   = def.label;
         List <RulePackDef> socialFightPacks = new List <RulePackDef>();
         if (otherConvo != null && (startedFight || (mattered && this.pawn.interactions.CheckSocialFightStart(endConversation, otherPawn))))
         {
             if (startedFight)
             {
                 socialFightPacks.Add(RulePackDefOfPsychology.Sentence_SocialFightConvoRecipientStarted);
             }
             else
             {
                 socialFightPacks.Add(RulePackDefOfPsychology.Sentence_SocialFightConvoInitiatorStarted);
             }
             this.startedFight = true;
             if (!this.waveGoodbye && otherConvo.convoLog != null && !otherConvo.startedFight)
             {
                 //The main conversation hediff was the other conversation, and didn't start a fight, so we have to add the extra sentence in after the fact.
                 Traverse.Create(otherConvo.convoLog).Field("extraSentencePacks").GetValue <List <RulePackDef> >().AddRange(socialFightPacks);
             }
         }
         if (this.waveGoodbye && this.pawn.Map != null)
         {
             RulePack      goodbyeText = new RulePack();
             FieldInfo     RuleStrings = typeof(RulePack).GetField("rulesStrings", BindingFlags.Instance | BindingFlags.NonPublic);
             List <string> text        = new List <string>(1);
             text.Add("r_logentry->" + talkDesc.Translate(convoTopic, pawn.Named("INITIATOR"), otherPawn.Named("RECIPIENT")));
             RuleStrings.SetValue(goodbyeText, text);
             endConversation.logRulesInitiator = goodbyeText;
             FieldInfo Symbol = typeof(InteractionDef).GetField("symbol", BindingFlags.Instance | BindingFlags.NonPublic);
             Symbol.SetValue(endConversation, Symbol.GetValue(InteractionDefOfPsychology.EndConversation));
             PlayLogEntry_InteractionConversation log = new PlayLogEntry_InteractionConversation(endConversation, pawn, this.otherPawn, socialFightPacks);
             Find.PlayLog.Add(log);
             convoLog = log;
             MoteMaker.MakeInteractionBubble(this.pawn, this.otherPawn, InteractionDefOf.Chitchat.interactionMote, InteractionDefOf.Chitchat.Symbol);
         }
     }
 }
Beispiel #15
0
 public override void Tick()
 {
     base.Tick();
     if (this.otherPawn == null)
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (!this.otherPawn.Spawned || !this.pawn.Spawned || !InteractionUtility.CanReceiveInteraction(this.pawn) || !InteractionUtility.CanReceiveInteraction(this.otherPawn))
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (this.pawn.Map != null && this.otherPawn.Map != null && ((this.pawn.Position - this.otherPawn.Position).LengthHorizontalSquared >= 54f || !GenSight.LineOfSight(this.pawn.Position, this.otherPawn.Position, this.pawn.Map, true)))
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (this.otherPawn.Dead || this.otherPawn.Downed || this.otherPawn.InAggroMentalState)
     {
         this.pawn.health.RemoveHediff(this);
         return;
     }
     if (this.pawn.IsHashIntervalTick(200))
     {
         /* When a conversation first starts, the mean time for it to last is 3 hours.
          * When it reaches half an hour, the mean time for it to continue is 2 hours.
          * When it reaches an hour, the mean time for it to continue is 1 hour.
          * When it surpasses 2 hours, it will on average last for half an hour more.
          * Conversations will thus usually not surpass 2 hours, and very rarely surpass 2 and a half hours, but are very likely to last up to an hour.
          */
         float mtb = 3f;
         if (this.ageTicks > GenDate.TicksPerHour * 2)
         {
             mtb = 0.5f;
         }
         else if (this.ageTicks > GenDate.TicksPerHour)
         {
             mtb = 1f;
         }
         else if (this.ageTicks > (GenDate.TicksPerHour / 2))
         {
             mtb = 2f;
         }
         if (pawn.story.traits.HasTrait(TraitDefOfPsychology.Chatty))
         {
             mtb *= 2f;
         }
         if (this.otherPawn.story.traits.HasTrait(TraitDefOfPsychology.Chatty))
         {
             mtb *= 2f;
         }
         if (Rand.MTBEventOccurs(mtb, GenDate.TicksPerHour, 200))
         {
             this.pawn.health.RemoveHediff(this);
             return;
         }
         else if (Rand.Value < 0.2f && this.pawn.Map != null)
         {
             MoteMaker.MakeInteractionBubble(this.pawn, otherPawn, InteractionDefOfPsychology.EndConversation.interactionMote, InteractionDefOfPsychology.EndConversation.Symbol);
         }
     }
 }
Beispiel #16
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);

            yield return(Toils_Reserve.Reserve(SpotIndex, 1, -1, null));

            yield return(new Toil
            {
                initAction = delegate
                {
                    Spot.ChangeState(Building_TeachingSpot.State.lesson, Building_TeachingSpot.LessonState.gathering);
                }
            });

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            Toil waitingTime = new Toil();

            waitingTime.defaultCompleteMode   = ToilCompleteMode.Delay;
            TeachingUtility.remainingDuration = TeachingUtility.ritualDuration;
            waitingTime.defaultDuration       = TeachingUtility.remainingDuration - 360;
            waitingTime.initAction            = delegate
            {
                // Spot.lastLessonTick = Find.TickManager.TicksGame;
                // HediffLeader hediff = TeachingUtility.leaderH(this.pawn);
                //if (hediff != null) hediff.lastLessonTick = Find.TickManager.TicksGame;
                report = "WaitingDesc".Translate();
                MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, ModTextures.waiting);
                Spot.ChangeState(Building_TeachingSpot.State.lesson, Building_TeachingSpot.LessonState.teaching);

                List <Thing> list = GenRadial.RadialDistinctThingsAround(this.pawn.Position, this.pawn.Map, 10f, true).ToList <Thing>();
                foreach (Thing current in list)
                {
                    Building_Chalkboard chalk = current as Building_Chalkboard;
                    bool flag2 = chalk != null;
                    if (flag2)
                    {
                        if (current.def.defName == "ChalkboardCL" && current.Faction == this.pawn.Faction)
                        {
                            if (current.GetRoom() == this.pawn.GetRoom())
                            {
                                string s = TeachingUtility.getLeaderType(this.pawn);
                                chalkboards.Add(chalk);
                                chalk.frame = -1;
                                this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false);
                            }
                        }
                    }
                }
            };

            yield return(waitingTime);


            for (int i = 0; i < 3; i++)
            {
                Toil teachingTime = new Toil();
                teachingTime.defaultCompleteMode  = ToilCompleteMode.Delay;
                TeachingUtility.remainingDuration = TeachingUtility.ritualDuration;
                teachingTime.defaultDuration      = TeachingUtility.remainingDuration - 120;
                teachingTime.initAction           = delegate
                {
                    string s = TeachingUtility.getLeaderType(this.pawn);
                    foreach (Building_Chalkboard chalk in chalkboards)
                    {
                        if (chalk != null)
                        {
                            if (s == "leader1")
                            {
                                chalk.state = 1;
                            }
                            else if (s == "leader2")
                            {
                                chalk.state = 2;
                            }
                            else if (s == "leader3")
                            {
                                chalk.state = 3;
                            }
                            else if (s == "leader4")
                            {
                                chalk.state = 4;
                            }
                            chalk.frame++;
                            this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false);
                        }
                    }

                    report = "TeachingDesc".Translate();

                    MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, iconList(this.pawn).RandomElement());
                };

                teachingTime.tickAction = delegate
                {
                    Pawn actor = this.pawn;
                    actor.skills.Learn(SkillDefOf.Social, 0.25f);
                    actor.GainComfortFromCellIfPossible();
                };

                yield return(teachingTime);
            }



            Toil finishingTime = new Toil();

            finishingTime.defaultCompleteMode = ToilCompleteMode.Delay;
            TeachingUtility.remainingDuration = TeachingUtility.ritualDuration;
            finishingTime.defaultDuration     = TeachingUtility.remainingDuration - 360;
            finishingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            finishingTime.initAction = delegate
            {
                report = "FinishLessonDesc".Translate();
                MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, iconList(this.pawn).RandomElement());
            };

            finishingTime.tickAction = delegate
            {
                if (tickC == 120 || tickC == 240 || tickC == 360)
                {
                    foreach (Building_Chalkboard chalk in chalkboards)
                    {
                        if (chalk != null)
                        {
                            if (chalk.frame > -1)
                            {
                                chalk.frame--;
                            }
                            this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false);
                        }
                    }
                }
                Pawn actor = this.pawn;
                actor.skills.Learn(SkillDefOf.Social, 0.25f);
                actor.GainComfortFromCellIfPossible();
                tickC++;
            };

            yield return(finishingTime);

            yield return(new Toil
            {
                initAction = delegate
                {
                    tickC = 0;
                    TeachingUtility.TeachingComplete(this.pawn, Spot);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield return(new Toil
            {
                initAction = delegate
                {
                    if (Spot != null)
                    {
                        if (Spot.currentLessonState != Building_TeachingSpot.LessonState.finished)
                        {
                            Spot.ChangeState(Building_TeachingSpot.State.lesson, Building_TeachingSpot.LessonState.finished);
                            //Map.GetComponent<MapComponent_SacrificeTracker>().ClearVariables();
                        }
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });


            this.AddFinishAction(() =>
            {
                foreach (Building_Chalkboard chalk in chalkboards)
                {
                    if (chalk != null)
                    {
                        chalk.frame = 0; chalk.state = 0; this.Map.mapDrawer.MapMeshDirty(chalk.Position, MapMeshFlag.Things, true, false);
                    }
                }

                if (Spot.currentLessonState == Building_TeachingSpot.LessonState.finishing ||
                    Spot.currentLessonState == Building_TeachingSpot.LessonState.finished)
                {
                    this.pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("TaughtCL"), null);
                }
            });

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.AddEndCondition(delegate
            {
                Thing thing = this.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            //this.FailOn(delegate
            //{
            //    IBillGiver billGiver = this.pawn.jobs.curJob.GetTarget(TargetIndex.A).Thing as IBillGiver;
            //    if (billGiver != null)
            //    {
            //        if (this.pawn.jobs.curJob.bill.DeletedOrDereferenced)
            //        {
            //            return true;
            //        }
            //        if (!billGiver.CurrentlyUsable())
            //        {
            //            return true;
            //        }
            //    }
            //    return false;
            //});
            //yield return ToilLogMessage("Pass 0 - Start");

            Toil toil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(new Toil {
                initAction = delegate { offerings = new List <Thing>(); }
            });

            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 2");}};
            yield return(Toils_Reserve.ReserveQueue(TargetIndex.B, 1));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 3");}};
            yield return(new Toil
            {
                initAction = delegate
                {
                    if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill;
                        }
                    }
                }
            });

            //yield return new Toil {initAction = delegate {Log.Message("Pass 4");}};
            yield return(Toils_Jump.JumpIf(toil, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 5");}};
            Toil toil2 = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, false);

            yield return(toil2);

            //yield return new Toil {initAction = delegate {Log.Message("Pass 6");}};
            Toil toil3 = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(toil3);

            //yield return new Toil {initAction = delegate {Log.Message("Pass 7");}};
            yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 8");}};
            yield return(JumpToCollectNextIntoHandsForBill(toil3, TargetIndex.B));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 9");}};
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDestroyedOrNull(TargetIndex.B));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 10");}};
            Toil toil4 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(toil4);

            //yield return new Toil {initAction = delegate {Log.Message("Pass 11");}};
            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, toil4, false));

            //yield return new Toil {initAction = delegate {Log.Message("Pass 12");}};
            yield return(new Toil {
                initAction = delegate {
                    if (offerings.Count > 0)
                    {
                        offerings.RemoveAll(x => x.DestroyedOrNull());
                    }
                    offerings.Add(TargetB.Thing);
                }
            });

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, toil2));

            yield return(toil);

            //yield return ToilLogMessage("Pass 13");
            Toil chantingTime = new Toil();

            chantingTime.defaultCompleteMode = ToilCompleteMode.Delay;
            chantingTime.defaultDuration     = CultUtility.ritualDuration;
            chantingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            chantingTime.PlaySustainerOrSound(CultsDefOf.RitualChanting);
            Texture2D deitySymbol = ((CosmicEntityDef)DropAltar.currentOfferingDeity.def).Symbol;

            chantingTime.initAction = delegate
            {
                if (deitySymbol != null)
                {
                    MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol);
                }
            };
            yield return(chantingTime);

            //yield return ToilLogMessage("Pass 14");
            //Toil 8: Execution of Prisoner
            yield return(new Toil
            {
                initAction = delegate
                {
                    CultUtility.OfferingComplete(this.pawn, DropAltar, DropAltar.currentOfferingDeity, offerings);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            //yield return ToilLogMessage("Pass 15 - Final");

            yield break;

            //this.AddEndCondition(delegate
            //{
            //    Thing thing = this.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
            //    if (thing is Building && !thing.Spawned)
            //    {
            //        return JobCondition.Incompletable;
            //    }
            //    return JobCondition.Ongoing;
            //});
            //this.FailOnBurningImmobile(TargetIndex.A);
            //Toil toil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            //yield return Toils_Reserve.Reserve(TargetIndex.A, 1);
            //yield return Toils_Reserve.ReserveQueue(TargetIndex.B, 1);
            //yield return new Toil
            //{
            //    initAction = delegate
            //    {
            //        if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1)
            //        {
            //            UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing;
            //            if (unfinishedThing != null)
            //            {
            //                unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill;
            //            }
            //        }
            //    }
            //};
            //yield return Toils_Jump.JumpIf(toil, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty<LocalTargetInfo>());
            //Toil toil2 = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B);
            //yield return toil2;
            //Toil toil3 = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
            //yield return toil3;
            //yield return Toils_Haul.StartCarryThing(TargetIndex.B);
            //yield return JumpToCollectNextIntoHandsForBill(toil3, TargetIndex.B);
            //yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B);
            //Toil toil4 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
            //yield return toil4;
            //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, toil4, false);
            //yield return Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, toil2);
            //yield return toil;
            //Toil chantingTime = new Toil();
            //chantingTime.defaultCompleteMode = ToilCompleteMode.Delay;
            //CultUtility.remainingDuration = CultUtility.ritualDuration;
            //chantingTime.defaultDuration = CultUtility.remainingDuration - 360;
            //chantingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            //chantingTime.PlaySustainerOrSound(CultDefOfs.RitualChanting);
            //Texture2D deitySymbol = ((CosmicEntityDef)DropAltar.currentOfferingDeity.def).Symbol;
            //chantingTime.initAction = delegate
            //{
            //    if (deitySymbol != null)
            //        MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol);
            //};
            //yield return chantingTime;
            ////Toil 8: Execution of Prisoner
            //yield return new Toil
            //{
            //    initAction = delegate
            //    {
            //        CultUtility.OfferingComplete(this.pawn, DropAltar, DropAltar.currentOfferingDeity);
            //    },
            //    defaultCompleteMode = ToilCompleteMode.Instant
            //};


            ////this.AddFinishAction(() =>
            ////{
            ////    if (this.pawn.CurJob.targetQueueB.Count == 0 &&
            ////        DropAltar.currentOfferingState == Building_SacrificialAltar.OfferingState.started)
            ////    //When the ritual is finished -- then let's give the thoughts
            ////    CultUtility.OfferingReady(this.pawn, DropAltar);

            ////});
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Commence fail checks!
            this.FailOnDestroyedOrNull(TargetIndex.A);

            yield return(Toils_Reserve.Reserve(AltarIndex, Building_SacrificialAltar.LyingSlotsCount));

            yield return(new Toil
            {
                initAction = delegate
                {
                    DropAltar.ChangeState(Building_SacrificialAltar.State.worshipping, Building_SacrificialAltar.WorshipState.gathering);
                }
            });

            //Who are we worshipping today?
            var    deitySymbol = ((CosmicEntityDef)DropAltar.currentWorshipDeity.def).Symbol;
            string deityLabel  = DropAltar.currentWorshipDeity.Label;

            Toil goToAltar = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            //Toil 0: Activate any nearby Worship Callers.
            yield return(new Toil
            {
                initAction = delegate
                {
                    Predicate <Thing> validator = (x => x.TryGetComp <CompWorshipCaller>() != null);
                    Thing worshipCaller = GenClosest.ClosestThingReachable(DropAltar.Position, DropAltar.Map,
                                                                           ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.ClosestTouch,
                                                                           TraverseParms.For(this.pawn, Danger.None, TraverseMode.ByPawn), 9999, validator, null, 0, -1, false, RegionType.Set_Passable, false);
                    if (worshipCaller != null)
                    {
                        WorshipCaller = worshipCaller;
                        this.job.SetTarget(TargetIndex.B, worshipCaller);
                    }
                    else
                    {
                        base.JumpToToil(goToAltar);
                    }
                }
            });

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.B, goToAltar));

            yield return(new Toil
            {
                initAction = delegate
                {
                    WorshipCaller.TryGetComp <CompWorshipCaller>().Use(Forced);
                }
            }.JumpIfDespawnedOrNullOrForbidden(TargetIndex.B, goToAltar));

            //Toil 1: Go to the altar.
            yield return(goToAltar);

            //Toil 2: Wait a bit for stragglers.
            Toil waitingTime = new Toil();

            waitingTime.defaultCompleteMode = ToilCompleteMode.Delay;
            waitingTime.defaultDuration     = CultUtility.ritualDuration;
            waitingTime.initAction          = delegate
            {
                report = "Cults_WaitingToStartSermon".Translate();
                DropAltar.ChangeState(Building_SacrificialAltar.State.worshipping, Building_SacrificialAltar.WorshipState.worshipping);
            };

            yield return(waitingTime);

            //Toil 3: Preach the sermon.
            Toil preachingTime = new Toil();

            preachingTime.defaultCompleteMode = ToilCompleteMode.Delay;
            preachingTime.defaultDuration     = CultUtility.ritualDuration;
            preachingTime.initAction          = delegate
            {
                report = "Cults_PreachingAbout".Translate(new object[]
                {
                    deityLabel
                });
                if (deitySymbol != null)
                {
                    MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol);
                }
            };
            preachingTime.tickAction = delegate
            {
                Pawn actor = this.pawn;
                actor.skills.Learn(SkillDefOf.Social, 0.25f);
                actor.GainComfortFromCellIfPossible();
            };

            yield return(preachingTime);

            //Toil 4: Time to pray
            Toil chantingTime = new Toil();

            chantingTime.defaultCompleteMode = ToilCompleteMode.Delay;
            chantingTime.defaultDuration     = CultUtility.ritualDuration;
            chantingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            chantingTime.PlaySustainerOrSound(CultsDefOf.RitualChanting);
            chantingTime.initAction = delegate
            {
                report = "Cults_PrayingTo".Translate(new object[]
                {
                    deityLabel
                });
                if (deitySymbol != null)
                {
                    MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol);
                }
            };
            chantingTime.tickAction = delegate
            {
                Pawn actor = this.pawn;
                actor.skills.Learn(SkillDefOf.Social, 0.25f);
                actor.GainComfortFromCellIfPossible();
            };

            yield return(chantingTime);

            //Toil 8: Execution of Prisoner
            yield return(new Toil
            {
                initAction = delegate
                {
                    //TaleRecorder.RecordTale(
                    // Of.ExecutedPrisoner, new object[]
                    //{
                    //    this.pawn,
                    //    this.Takee
                    //});
                    CultUtility.WorshipComplete(this.pawn, DropAltar, DropAltar.currentWorshipDeity);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield return(new Toil
            {
                initAction = delegate
                {
                    if (DropAltar != null)
                    {
                        if (DropAltar.currentWorshipState != Building_SacrificialAltar.WorshipState.finished)
                        {
                            DropAltar.ChangeState(Building_SacrificialAltar.State.worshipping, Building_SacrificialAltar.WorshipState.finished);
                            //Map.GetComponent<MapComponent_SacrificeTracker>().ClearVariables();
                        }
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });


            this.AddFinishAction(() =>
            {
                //When the ritual is finished -- then let's give the thoughts
                if (DropAltar.currentWorshipState == Building_SacrificialAltar.WorshipState.finishing ||
                    DropAltar.currentWorshipState == Building_SacrificialAltar.WorshipState.finished)
                {
                    Cthulhu.Utility.DebugReport("Called end tick check");
                    CultUtility.HoldWorshipTickCheckEnd(this.pawn);
                }
            });

            yield break;
        }
Beispiel #19
0
        protected override bool TryCastShot()
        {
            bool flag = false;
            CompAbilityUserMight comp = base.CasterPawn.GetComp <CompAbilityUserMight>();
            MightPowerSkill      pwr  = base.CasterPawn.GetComp <CompAbilityUserMight>().MightData.MightPowerSkill_AnimalFriend.FirstOrDefault((MightPowerSkill x) => x.label == "TM_AnimalFriend_pwr");
            MightPowerSkill      ver  = base.CasterPawn.GetComp <CompAbilityUserMight>().MightData.MightPowerSkill_AnimalFriend.FirstOrDefault((MightPowerSkill x) => x.label == "TM_AnimalFriend_ver");
            Pawn pawn   = this.CasterPawn;
            Pawn animal = this.currentTarget.Thing as Pawn;

            if (animal != null && animal.RaceProps.Animal && animal.RaceProps.IsFlesh)
            {
                Pawn oldbond = comp.bondedPet;
                if (animal == comp.bondedPet)
                {
                    Hediff animalBondHD = oldbond.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("TM_RangerBondHD"));
                    if (animalBondHD != null && Rand.Chance(((1f + animalBondHD.ageTicks / 6000000) - oldbond.RaceProps.wildness)))
                    {
                        Messages.Message("TM_BondedAnimalReleaseToColony".Translate(
                                             oldbond.LabelShort,
                                             pawn.LabelShort
                                             ), MessageTypeDefOf.NeutralEvent);
                        MoteMaker.MakeInteractionBubble(oldbond, pawn, InteractionDefOf.Nuzzle.interactionMote, InteractionDefOf.Nuzzle.GetSymbol());
                        oldbond.health.RemoveHediff(animalBondHD);
                        DefMap <TrainableDef, int> steps = Traverse.Create(root: oldbond.training).Field(name: "steps").GetValue <DefMap <TrainableDef, int> >();
                        steps[TrainableDefOf.Tameness]  = 1;
                        steps[TrainableDefOf.Obedience] = 0;
                        steps[TrainableDefOf.Release]   = 0;
                        steps[TorannMagicDefOf.Haul]    = 0;
                        steps[TorannMagicDefOf.Rescue]  = 0;
                        comp.bondedPet = null;
                    }
                    else
                    {
                        Messages.Message("TM_BondedAnimalRelease".Translate(
                                             oldbond.LabelShort,
                                             pawn.LabelShort
                                             ), MessageTypeDefOf.NeutralEvent);
                        FleckMaker.ThrowSmoke(oldbond.DrawPos, oldbond.Map, 3f);
                        oldbond.Destroy();
                    }
                }
                else if (animal.Faction != null && animal.Faction != pawn.Faction)
                {
                    Messages.Message("TM_AnimalHasAllegience".Translate(
                                         ), MessageTypeDefOf.RejectInput);
                }
                else if (animal.health != null && animal.health.hediffSet != null && animal.health.hediffSet.HasHediff(HediffDef.Named("TM_RangerBondHD")))
                {
                    Messages.Message("TM_AnimalAlreadyHasBond".Translate(animal.LabelShort
                                                                         ), MessageTypeDefOf.RejectInput);
                }
                else
                {
                    if (animal.RaceProps.intelligence == Intelligence.Animal) // == TrainableIntelligenceDefOf.Intermediate || animal.RaceProps.TrainableIntelligence == TrainableIntelligenceDefOf.Advanced)
                    {
                        if ((animal.RaceProps.wildness <= .7f) || (animal.RaceProps.wildness <= .8f && pwr.level == 1) || (animal.RaceProps.wildness <= .9f && pwr.level == 2) || pwr.level == 3)
                        {
                            if (Rand.Chance(.6f + (.05f * pwr.level)) && Rand.Chance(((.7f + (.1f * pwr.level)) - animal.RaceProps.wildness) * 10))
                            {
                                if (comp.bondedPet != null && comp.bondedPet != animal)
                                {
                                    if (!oldbond.Destroyed)
                                    {
                                        if (!comp.bondedPet.Dead)
                                        {
                                            //bonding with another pet without first pet being dead or destroyed
                                            comp.bondedPet = null;
                                            Messages.Message("TM_BondedAnimalRelease".Translate(
                                                                 oldbond.LabelShort,
                                                                 pawn.LabelShort
                                                                 ), MessageTypeDefOf.NeutralEvent);
                                            if (oldbond.Map != null)
                                            {
                                                FleckMaker.ThrowSmoke(oldbond.DrawPos, oldbond.Map, 3f);
                                            }
                                            else
                                            {
                                                oldbond.ParentHolder.GetDirectlyHeldThings().Remove(oldbond);
                                            }
                                            oldbond.Destroy();
                                        }
                                    }
                                }
                                animal.SetFaction(pawn.Faction);
                                HealthUtility.AdjustSeverity(animal, TorannMagicDefOf.TM_RangerBondHD, -4f);
                                HealthUtility.AdjustSeverity(animal, TorannMagicDefOf.TM_RangerBondHD, .5f + ver.level);
                                comp.bondedPet = animal;
                                MoteMaker.MakeInteractionBubble(animal, pawn, InteractionDefOf.Nuzzle.interactionMote, InteractionDefOf.Nuzzle.GetSymbol());
                                TM_Action.TrainAnimalFull(animal, pawn);
                            }
                            else
                            {
                                Messages.Message("TM_FailedRangerBond".Translate(
                                                     animal.LabelShort,
                                                     pawn.LabelShort,
                                                     (Mathf.Clamp(Mathf.RoundToInt(((.7f + (.1f * pwr.level)) - animal.RaceProps.wildness) * 1000f), 0, 100 - (40 - (5 * pwr.level))))
                                                     ), MessageTypeDefOf.NeutralEvent);
                                if (animal.Faction == null && Rand.Chance(animal.RaceProps.manhunterOnTameFailChance))
                                {
                                    animal.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.Manhunter, null, true, false, null);
                                }
                            }
                        }
                        else
                        {
                            Messages.Message("TM_RangerNotExperienced".Translate(
                                                 animal.LabelShort,
                                                 pawn.LabelShort,
                                                 (animal.RaceProps.wildness * 100).ToString("F"),
                                                 (.7f + .1f * pwr.level) * 100
                                                 ), MessageTypeDefOf.NeutralEvent);
                        }
                    }
                    else
                    {
                        Messages.Message("TM_AnimalIncapableOfBond".Translate(
                                             animal.LabelShort,
                                             pawn.LabelShort
                                             ), MessageTypeDefOf.NeutralEvent);
                    }
                }
            }
            this.PostCastShot(flag, out flag);
            return(flag);
        }