Пример #1
0
        private bool TryHealFarmer()
        {
            if (this.medkits > 0 && this.player.health < this.player.maxHealth && this.player.health > 0)
            {
                int healthBonus = (this.player.maxHealth / 100) * (this.player.getFriendshipHeartLevelForNPC(this.npc.Name) / 2); // % health bonus based on friendship hearts
                int health      = Math.Max(10, (1 / this.player.health * 10) + Game1.random.Next(0, (int)(this.player.maxHealth * .1f))) + healthBonus;
                this.player.health += health;
                this.healCooldown   = HEAL_COUNTDOWN;
                this.medkits--;

                if (this.player.health > this.player.maxHealth)
                {
                    this.player.health = this.player.maxHealth;
                }

                Game1.drawDialogue(this.npc, DialogueHelper.GetDialogueString(this.npc, "heal"));
                Game1.addHUDMessage(new HUDMessage(this.Csm.ContentLoader.LoadString("Strings/Strings:healed", this.npc.displayName, health), HUDMessage.health_type));
                this.hud.GlowSkill("doctor", Color.Lime, HEAL_COUNTDOWN / 60);
                this.Monitor.Log($"{this.npc.Name} healed you! Remaining medkits: {this.medkits}", LogLevel.Info);
                return(true);
            }

            if (this.medkits == 0)
            {
                this.Monitor.Log($"No medkits. {this.npc.Name} can't heal you!", LogLevel.Info);
                Game1.drawDialogue(this.npc, DialogueHelper.GetDialogueString(this.npc, "nomedkits"));
                this.medkits = -1;
            }

            return(false);
        }
Пример #2
0
        /// <summary>
        /// Setup companion for new day
        /// </summary>
        public void NewDaySetup()
        {
            if (this.CurrentStateFlag != StateFlag.RESET)
            {
                throw new InvalidStateException($"State machine {this.Name} must be in reset state!");
            }

            // Today is festival day? Player can't recruit this companion
            if (Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason))
            {
                this.Monitor.Log($"{this.Name} is unavailable to recruit due to festival today.");
                this.MakeUnavailable();
                return;
            }

            // Setup dialogues for companion for this day
            DialogueHelper.SetupCompanionDialogues(this.Companion, this.ContentLoader.LoadStrings($"Dialogue/{this.Name}"));

            this.RecruitedToday  = false;
            this.SuggestedToday  = false;
            this.CanSuggestToday = Game1.random.NextDouble() > .5f &&
                                   !(this.Companion.isMarried() && SDate.Now().DayOfWeek == DayOfWeek.Monday);
            this.SpokenDialogues.Clear();
            this.MakeAvailable();
            if (this.CanSuggestToday)
            {
                this.Monitor.Log($"{this.Name} can suggest adventure today!");
            }
        }
Пример #3
0
        /// <summary>
        /// Setup companion for new day
        /// </summary>
        public void NewDaySetup()
        {
            if (this.CurrentStateFlag != StateFlag.RESET)
            {
                throw new InvalidStateException($"State machine {this.Name} must be in reset state!");
            }

            // Today is festival day? Player can't recruit this companion
            if (Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason))
            {
                this.Monitor.Log($"{this.Name} is unavailable to recruit due to festival today.");
                this.MakeUnavailable();
                return;
            }

            // Setup dialogues for companion for this day
            DialogueHelper.SetupCompanionDialogues(this.Companion, this.ContentLoader.LoadStrings($"Dialogue/{this.Name}"));

            // Spoused or married with her/him? Enhance dialogues with extra spouse dialogues for this day
            if (Helper.IsSpouseMarriedToFarmer(this.Companion, this.CompanionManager.Farmer) && this.ContentLoader.CanLoad($"Dialogue/{this.Name}Spouse"))
            {
                DialogueHelper.SetupCompanionDialogues(this.Companion, this.ContentLoader.LoadStrings($"Dialogue/{this.Name}Spouse"));
            }

            this.RecruitedToday = false;
            this.MakeAvailable();
        }
Пример #4
0
        private void GameLoop_TimeChanged(object sender, TimeChangedEventArgs e)
        {
            this.StateMachine.Companion.clearSchedule();

            if (e.NewTime >= 2200)
            {
                NPC      companion         = this.StateMachine.Companion;
                Dialogue dismissalDialogue = new Dialogue(DialogueHelper.GetDialogueString(companion, "companionDismissAuto"), companion);
                this.dismissalDialogue = dismissalDialogue;
                this.StateMachine.Companion.doEmote(24);
                this.StateMachine.Companion.updateEmote(Game1.currentGameTime);
                DialogueHelper.DrawDialogue(dismissalDialogue);
            }

            MineShaft mines = this.StateMachine.Companion.currentLocation as MineShaft;

            // Fix spawn ladder if area is infested and all monsters is killed but NPC following us
            if (mines != null && mines.mustKillAllMonstersToAdvance())
            {
                var monsters = from c in mines.characters where c.IsMonster select c;
                if (monsters.Count() == 0)
                {
                    Vector2 vector2 = this.StateMachine.Reflection.GetProperty <Vector2>(mines, "tileBeneathLadder").GetValue();
                    if (mines.getTileIndexAt(Utility.Vector2ToPoint(vector2), "Buildings") == -1)
                    {
                        mines.createLadderAt(vector2, "newArtifact");
                    }
                }
            }
        }
Пример #5
0
    public void Ext()
    {
        DialogueHelper dialogue = new DialogueHelper();

        foreach (var t in Text)
        {
            switch (t.type)
            {
            case DialogeType.general:
                dialogue.AddNextText(t.text, this);
                break;

            case DialogeType.choice:
                dialogue.AddChoiceText(t.question, t.answer);
                break;

            case DialogeType.aside:
                dialogue.AddAside(t.text);
                break;

            default:
                break;
            }
        }
    }
Пример #6
0
        private void DoFightSpeak()
        {
            // Cooldown not expired? Say nothing
            if (this.fightBubbleCooldown != 0)
            {
                return;
            }

            if (Game1.random.NextDouble() < this.fightSpeechTriggerThres && DialogueHelper.GetBubbleString(this.bubbles, this.follower, "fight", out string text))
            {
                bool isRed = this.ai.Csm.HasSkill("warrior") && Game1.random.NextDouble() < 0.1;
                this.follower.showTextAboveHead(text, isRed ? 2 : -1);
                this.fightBubbleCooldown = 600;
            }
            else if (this.ai.Csm.HasSkill("warrior") && Game1.random.NextDouble() < this.fightSpeechTriggerThres / 2)
            {
                this.follower.clearTextAboveHead();
                this.follower.doEmote(12);
                this.fightBubbleCooldown = 550;
            }
            else if (Game1.random.NextDouble() > (this.fightSpeechTriggerThres + this.fightSpeechTriggerThres * .33f))
            {
                this.follower.clearTextAboveHead();
                this.follower.doEmote(16);
                this.fightBubbleCooldown = 500;
            }
        }
Пример #7
0
        public override void Entry()
        {
            this.ai = new AI_StateMachine(this.StateMachine.Companion, this.StateMachine.CompanionManager.Farmer, this.Events, this.StateMachine.Monitor);

            this.StateMachine.Companion.faceTowardFarmerTimer = 0;
            this.StateMachine.Companion.movementPause         = 0;
            this.StateMachine.Companion.followSchedule        = false;
            this.StateMachine.Companion.Schedule            = null;
            this.StateMachine.Companion.controller          = null;
            this.StateMachine.Companion.temporaryController = null;
            this.StateMachine.Companion.eventActor          = true;
            this.StateMachine.Companion.farmerPassesThrough = true;

            this.Events.GameLoop.UpdateTicked += this.GameLoop_UpdateTicked;
            this.Events.GameLoop.TimeChanged  += this.GameLoop_TimeChanged;
            this.Events.Player.Warped         += this.Player_Warped;

            if (this.BuffManager.HasAssignableBuffs())
            {
                this.BuffManager.AssignBuffs();
            }
            else
            {
                this.StateMachine.Monitor.Log($"Companion {this.StateMachine.Name} has no buffs defined!", LogLevel.Alert);
            }

            if (DialogueHelper.GetVariousDialogueString(this.StateMachine.Companion, "companionRecruited", out string dialogueText))
            {
                this.StateMachine.Companion.setNewDialogue(dialogueText);
            }
            this.CanCreateDialogue = true;

            this.ai.Setup();
        }
 // Use this for initialization
 void Start()
 {
     pc = GameObject.Find("Character").GetComponent("PlayerController") as PlayerController;
     controller = GameObject.Find ("SceneControl");
     dh = (DialogueHelper)controller.GetComponent(typeof(DialogueHelper));
     scs = (SceneControlScript)controller.GetComponent(typeof(SceneControlScript));
     x = transform.position.x;
     y = transform.position.y;
 }
 // Update is called once per frame
 void Update()
 {
     dist = Mathf.Abs(pc.x - x) + Mathf.Abs(pc.y - y);
     if(!talking && dist<10){
         talking = true;
         //c = controller.AddComponent("DialogueHelper");
         dh = (DialogueHelper)controller.GetComponent(typeof(DialogueHelper));
         dh.parseDialogueTree(ta.text);
         dh.start = true;
     }
 }
Пример #10
0
        public override void Entry()
        {
            this.ai            = new AI_StateMachine(this.StateMachine, this.StateMachine.CompanionManager.Hud, this.Events, this.monitor);
            this.timeOfRecruit = Game1.timeOfDay;

            if (this.StateMachine.Companion.doingEndOfRouteAnimation.Value)
            {
                this.FinishScheduleAnimation();
            }

            this.StateMachine.Companion.faceTowardFarmerTimer = 0;
            this.StateMachine.Companion.movementPause         = 0;
            this.StateMachine.Companion.followSchedule        = false;
            this.StateMachine.Companion.Schedule            = null;
            this.StateMachine.Companion.controller          = null;
            this.StateMachine.Companion.temporaryController = null;
            this.StateMachine.Companion.eventActor          = true;
            this.StateMachine.Companion.farmerPassesThrough = true;

            this.Events.GameLoop.UpdateTicked   += this.GameLoop_UpdateTicked;
            this.Events.GameLoop.TimeChanged    += this.GameLoop_TimeChanged;
            this.Events.Player.Warped           += this.Player_Warped;
            this.Events.Input.ButtonPressed     += this.Input_ButtonPressed;
            this.SpecialEvents.RenderedLocation += this.SpecialEvents_RenderedLocation;

            this.recruitedDialogue = DialogueHelper.GenerateDialogue(this.StateMachine.Companion, "companionRecruited");
            this.CanPerformAction  = true;

            if (this.recruitedDialogue != null)
            {
                this.StateMachine.Companion.CurrentDialogue.Push(this.recruitedDialogue);
            }

            foreach (string skill in this.StateMachine.Metadata.PersonalSkills)
            {
                string text = this.StateMachine.ContentLoader.LoadString($"Strings/Strings:skill.{skill}", this.StateMachine.Companion.displayName)
                              + Environment.NewLine
                              + this.StateMachine.ContentLoader.LoadString($"Strings/Strings:skillDescription.{skill}").Replace("#", Environment.NewLine);
                this.StateMachine.CompanionManager.Hud.AddSkill(skill, text);
            }

            this.StateMachine.CompanionManager.Hud.AssignCompanion(this.StateMachine.Companion);
            this.BuffManager.AssignBuffs();
            this.ai.Setup();

            if (this.BuffManager.HasProsthetics())
            {
                var key  = this.StateMachine.CompanionManager.Config.ChangeBuffButton;
                var desc = this.StateMachine.ContentLoader.LoadString("Strings/Strings:prosteticsChangeButton", key, this.StateMachine.Companion.displayName);
                this.StateMachine.CompanionManager.Hud.AddKey(key, desc);
            }
        }
Пример #11
0
        private Dialogue GenerateLocationDialogue(GameLocation location, NPC companion)
        {
            if (DialogueHelper.GenerateStaticDialogue(companion, location, "companionOnce") is CompanionDialogue dialogueOnce &&
                !this.StateMachine.CompanionManager.Farmer.hasOrWillReceiveMail(dialogueOnce.Tag))
            {
                // Remember only once spoken dialogue
                dialogueOnce.Remember = true;
                return(dialogueOnce);
            }

            // Generate standard companion various dialogue if no once dialogue defined or once dialogue spoken
            return(DialogueHelper.GenerateDialogue(companion, location, "companion"));
        }
Пример #12
0
        public override void Entry()
        {
            this.ai = new AI_StateMachine(this.StateMachine, this.StateMachine.CompanionManager.Hud, this.Events, this.monitor);

            if (this.StateMachine.Companion.doingEndOfRouteAnimation.Value)
            {
                this.FinishScheduleAnimation();
            }

            this.StateMachine.Companion.faceTowardFarmerTimer = 0;
            this.StateMachine.Companion.movementPause         = 0;
            this.StateMachine.Companion.followSchedule        = false;
            this.StateMachine.Companion.Schedule            = null;
            this.StateMachine.Companion.controller          = null;
            this.StateMachine.Companion.temporaryController = null;
            this.StateMachine.Companion.eventActor          = true;
            this.StateMachine.Companion.farmerPassesThrough = true;

            if (this.StateMachine.Companion.isMarried() && Patches.SpouseReturnHomePatch.recruitedSpouses.IndexOf(this.StateMachine.Companion.Name) < 0)
            {
                // Avoid returning recruited wife/husband to FarmHouse when is on Farm and it's after 1pm
                Patches.SpouseReturnHomePatch.recruitedSpouses.Add(this.StateMachine.Companion.Name);
            }

            this.Events.GameLoop.UpdateTicked   += this.GameLoop_UpdateTicked;
            this.Events.GameLoop.TimeChanged    += this.GameLoop_TimeChanged;
            this.Events.Player.Warped           += this.Player_Warped;
            this.SpecialEvents.RenderedLocation += this.SpecialEvents_RenderedLocation;

            if (DialogueHelper.GetVariousDialogueString(this.StateMachine.Companion, "companionRecruited", out string dialogueText))
            {
                this.StateMachine.Companion.setNewDialogue(dialogueText);
            }
            this.CanCreateDialogue = true;

            foreach (string skill in this.StateMachine.Metadata.PersonalSkills)
            {
                string text = this.StateMachine.ContentLoader.LoadString($"Strings/Strings:skill.{skill}", this.StateMachine.Companion.displayName)
                              + Environment.NewLine
                              + this.StateMachine.ContentLoader.LoadString($"Strings/Strings:skillDescription.{skill}").Replace("#", Environment.NewLine);
                this.StateMachine.CompanionManager.Hud.AddSkill(skill, text);
            }

            this.StateMachine.CompanionManager.Hud.AssignCompanion(this.StateMachine.Companion);
            this.BuffManager.AssignBuffs();
            this.ai.Setup();
        }
Пример #13
0
        private void ReactOnAsk(NPC companion, Farmer leader, string action)
        {
            switch (action)
            {
            case "dismiss":
                Dialogue dismissalDialogue = new Dialogue(DialogueHelper.GetDialogueString(companion, "companionDismiss"), companion);
                this.dismissalDialogue = dismissalDialogue;
                DialogueHelper.DrawDialogue(dismissalDialogue);
                break;

            case "bag":
                Chest bag = this.StateMachine.Bag;
                this.StateMachine.Companion.currentLocation.playSound("openBox");
                Game1.activeClickableMenu = new ItemGrabMenu(bag.items, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), new ItemGrabMenu.behaviorOnItemSelect(bag.grabItemFromInventory), this.StateMachine.Companion.displayName, new ItemGrabMenu.behaviorOnItemSelect(bag.grabItemFromChest), false, true, true, true, true, 1, null, -1, this.StateMachine.Companion);
                break;
            }
        }
Пример #14
0
        private void ReactOnAnswer(NPC n, Farmer leader)
        {
            if (leader.getFriendshipHeartLevelForNPC(n.Name) <= 4 || Game1.timeOfDay >= 2200)
            {
                Dialogue rejectionDialogue = new Dialogue(
                    DialogueHelper.GetDialogueString(
                        n, Game1.timeOfDay >= 2200 ? "companionRejectedNight" : "companionRejected"), n);

                this.rejectionDialogue = rejectionDialogue;
                DialogueHelper.DrawDialogue(rejectionDialogue);
            }
            else
            {
                Dialogue acceptalDialogue = new Dialogue(DialogueHelper.GetDialogueString(n, "companionAccepted"), n);

                this.acceptalDialogue = acceptalDialogue;
                DialogueHelper.DrawDialogue(acceptalDialogue);
            }
        }
Пример #15
0
        private void Player_Warped(object sender, WarpedEventArgs e)
        {
            NPC companion = this.StateMachine.Companion;
            Dictionary <string, string> bubbles = this.StateMachine.ContentLoader.LoadStrings("Strings/SpeechBubbles");

            // Warp companion to farmer if it's needed
            if (companion.currentLocation != e.NewLocation)
            {
                this.ai.ChangeLocation(e.NewLocation);
            }

            // Show above head bubble text for location
            if (Game1.random.NextDouble() > .66f && DialogueHelper.GetBubbleString(bubbles, companion, e.NewLocation, out string bubble))
            {
                companion.showTextAboveHead(bubble, preTimer: 250);
            }

            // Push new location dialogue
            this.TryPushLocationDialogue(e.NewLocation, true);
        }
Пример #16
0
        /// <summary>
        /// Try find a gift reaction dialogue text for gifted object to an NPC
        /// </summary>
        /// <param name="npc">NPC had recieved a gift</param>
        /// <param name="obj">Gifted item recieved by this NPC</param>
        /// <param name="dialogue">A reaction dialogue text for this gifted item to this NPC</param>
        /// <returns>True if any gift reaction dialogue was found, otherwise false</returns>
        public static bool FetchGiftReaction(NPC npc, SObject obj, out string dialogue, string suffix = "")
        {
            string[] possibleKeys = new string[] {
                $"GiftReaction_{obj.Name.Replace(' ', '_')}{suffix}",
                $"GiftReactionCategory_{obj.Category}{suffix}",
                $"GiftReactionHoney_{obj.honeyType.Value}{suffix}",
                $"GiftReactionHoney_{(obj.honeyType.Value.HasValue ? "Any" : "")}{suffix}",
                $"GiftReactionPreserved_{obj.preserve.Value}{suffix}",
                $"GiftReactionPreserved_{(obj.preserve.Value.HasValue ? "Any" : "")}{suffix}",
            };

            foreach (string dialogueKey in possibleKeys)
            {
                if (DialogueHelper.GetRawDialogue(npc.Dialogue, dialogueKey, out KeyValuePair <string, string> reaction))
                {
                    dialogue = reaction.Value;
                    return(true);
                }
            }

            dialogue = "";
            return(false);
        }
Пример #17
0
        public Dialogue GenerateLocationDialogue(GameLocation location, string suffix = "")
        {
            NPC companion = this.Companion;

            // Try generate only once spoken dialogue in game save
            if (DialogueHelper.GenerateStaticDialogue(companion, location, $"companionOnce{suffix}") is CompanionDialogue dialogueOnce &&
                !this.CompanionManager.Farmer.hasOrWillReceiveMail(dialogueOnce.Tag))
            {
                // Remember only once spoken dialogue (as received mail. Keep it forever in loaded game after game saved)
                dialogueOnce.Remember = true;
                return(dialogueOnce);
            }

            // Try generate standard companion various dialogue. This dialogue can be shown only once per day (per recruited companion session)
            if (DialogueHelper.GenerateDialogue(companion, location, $"companion{suffix}") is CompanionDialogue dialogue && !this.SpokenDialogues.Contains(dialogue.Tag))
            {
                dialogue.SpecialAttributes.Add("session"); // Remember this dialogue in this companion session when will be spoken
                return(dialogue);
            }

            // Try generate dialogue which can be shown repeately in day (current companion session). If none defined, returns null
            return(DialogueHelper.GenerateDialogue(companion, location, "companionRepeat"));
        }
Пример #18
0
        private bool TryPushLocationDialogue(GameLocation location)
        {
            NPC              companion   = this.StateMachine.Companion;
            Dialogue         newDialogue = DialogueHelper.GenerateDialogue(companion, location, "companion");
            Stack <Dialogue> temp        = new Stack <Dialogue>(this.StateMachine.Companion.CurrentDialogue.Count);

            if ((newDialogue == null && this.currentLocationDialogue == null) || (newDialogue != null && newDialogue.Equals(this.currentLocationDialogue)))
            {
                return(false);
            }

            // Remove old location dialogue
            while (this.StateMachine.Companion.CurrentDialogue.Count > 0)
            {
                Dialogue d = this.StateMachine.Companion.CurrentDialogue.Pop();

                if (!d.Equals(this.currentLocationDialogue))
                {
                    temp.Push(d);
                }
            }

            while (temp.Count > 0)
            {
                this.StateMachine.Companion.CurrentDialogue.Push(temp.Pop());
            }

            this.currentLocationDialogue = newDialogue;

            if (newDialogue != null)
            {
                this.StateMachine.Companion.CurrentDialogue.Push(newDialogue); // Push new location dialogue
                return(true);
            }

            return(false);
        }
Пример #19
0
    private void InterpretCommand(string command)
    {
        if (command.StartsWith("=>")) //Go to tab
        {
            command = command.Replace("=>", "").Replace(" ", "");
            curLine = keyLines[command];
        }
        else if (command.StartsWith("if"))                                                          //Conditional
        {
            string[] parts     = command.Split(',');                                                //Splits condition from reaction
            string   condition = parts[0].Replace("if ", "").Replace(" ", "");                      //Condition part
            string   action    = parts[1].Replace("do ", "").Replace("then ", "").Replace(" ", ""); //Reaction part
            string[] conds     = condition.Split('&');

            //If all conditions are met, you the action will complete
            foreach (string c in conds)
            {
                if (!DialogueHelper.CheckCondition(c))
                {
                    return;
                }
            }
            InterpretCommand(action);
        }
        else if (command.StartsWith("Quest")) //QuestLogic
        {
            Quest q = DialogueHelper.GetQuestFromCommand(command);
            if (command.Contains(".Finish"))
            {
                GameManager.questManager.FinishQuest(q);
            }
            else if (command.Contains(".Advance") || command.Contains(".Start"))
            {
                GameManager.questManager.AdvanceQuest(q);
            }
        }
    }
Пример #20
0
        public void NewDaySetup()
        {
            if (this.CurrentStateFlag != StateFlag.RESET)
            {
                throw new InvalidStateException($"State machine {this.Name} must be in reset state!");
            }

            if (Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason))
            {
                this.Monitor.Log($"{this.Name} is unavailable to recruit due to festival today.");
                this.MakeUnavailable();
                return;
            }

            DialogueHelper.SetupCompanionDialogues(this.Companion, this.ContentLoader.LoadStrings($"Dialogue/{this.Name}"));

            if (Helper.IsSpouseMarriedToFarmer(this.Companion, this.CompanionManager.Farmer))
            {
                DialogueHelper.SetupCompanionDialogues(this.Companion, this.ContentLoader.LoadStrings($"Dialogue/{this.Name}Spouse"));
            }

            this.RecruitedToday = false;
            this.MakeAvailable();
        }
Пример #21
0
        /// <summary>
        /// Try find a gift reaction dialogue text for gifted object to an NPC
        /// </summary>
        /// <param name="npc">NPC had recieved a gift</param>
        /// <param name="obj">Gifted item recieved by this NPC</param>
        /// <param name="dialogue">A reaction dialogue text for this gifted item to this NPC</param>
        /// <returns>True if any gift reaction dialogue was found, otherwise false</returns>
        public static bool FetchGiftReaction(NPC npc, SObject obj, out string dialogue, string suffix = "")
        {
            HashSet <string> possibleKeys = new () {
                $"GiftReaction_{obj.Name.Replace(' ', '_')}{suffix}",
                $"GiftReactionCategory_{obj.Category}{suffix}",
                $"GiftReactionPreserved_{obj.preserve.Value}{suffix}",
                $"GiftReactionPreserved_{(obj.preserve.Value.HasValue ? "Any" : "")}{suffix}",
            };

            // Add item context tags as possibly dialogue lines for gift reactions
            possibleKeys.UnionWith(obj.GetContextTags().Select(tag => $"GiftReactionTag_{tag}"));

            foreach (string dialogueKey in possibleKeys)
            {
                if (DialogueHelper.GetRawDialogue(npc.Dialogue, dialogueKey, out KeyValuePair <string, string> reaction))
                {
                    dialogue = reaction.Value;
                    return(true);
                }
            }

            dialogue = "";
            return(false);
        }
Пример #22
0
        private void GameLoop_TimeChanged(object sender, TimeChangedEventArgs e)
        {
            this.StateMachine.Companion.clearSchedule();

            if (e.NewTime >= 2200)
            {
                NPC      companion         = this.StateMachine.Companion;
                Dialogue dismissalDialogue = new Dialogue(DialogueHelper.GetSpecificDialogueText(companion, this.StateMachine.CompanionManager.Farmer, "companionDismissAuto"), companion);
                this.dismissalDialogue = dismissalDialogue;
                this.StateMachine.Companion.doEmote(24);
                this.StateMachine.Companion.updateEmote(Game1.currentGameTime);
                DialogueHelper.DrawDialogue(dismissalDialogue);
            }

            // Fix spawn ladder if area is infested and all monsters is killed but NPC following us
            if (this.StateMachine.Companion.currentLocation is MineShaft mines && mines.mustKillAllMonstersToAdvance())
            {
                var monsters = from c in mines.characters where c.IsMonster select c;
                if (monsters.Count() == 0)
                {
                    Vector2 vector2 = this.StateMachine.Reflection.GetProperty <Vector2>(mines, "tileBeneathLadder").GetValue();
                    if (mines.getTileIndexAt(Utility.Vector2ToPoint(vector2), "Buildings") == -1)
                    {
                        mines.createLadderAt(vector2, "newArtifact");
                    }
                }
            }

            // Try to push new or change location dialogue randomly until or no location dialogue was pushed
            int until = this.dialoguePushTime + (Game1.random.Next(1, 3) * 10);

            if ((e.NewTime > until || this.currentLocationDialogue == null))
            {
                this.TryPushLocationDialogue(this.StateMachine.Companion.currentLocation);
            }

            // Remove recruited dialogue if this dialogue not spoken until a hour from while companion was recruited
            if (this.recruitedDialogue != null && e.NewTime > this.timeOfRecruit + 100)
            {
                // TODO: Use here Remove old dialogue method when rebased onto branch or merged branch which has this util
                Stack <Dialogue> temp = new Stack <Dialogue>(this.StateMachine.Companion.CurrentDialogue.Count);

                while (this.StateMachine.Companion.CurrentDialogue.Count > 0)
                {
                    Dialogue d = this.StateMachine.Companion.CurrentDialogue.Pop();

                    if (!d.Equals(this.recruitedDialogue))
                    {
                        temp.Push(d);
                    }
                    else
                    {
                        this.monitor.Log($"Recruited dialogue was removed from {this.StateMachine.Name}'s stack due to NPC was recruited a hour ago and dialogue still not spoken.");
                    }
                }

                while (temp.Count > 0)
                {
                    this.StateMachine.Companion.CurrentDialogue.Push(temp.Pop());
                }
            }
        }