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); }
/// <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!"); } }
/// <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(); }
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"); } } } }
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; } } }
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; } }
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; } }
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); } }
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")); }
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(); }
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; } }
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); } }
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); }
/// <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); }
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")); }
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); }
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); } } }
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(); }
/// <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); }
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()); } } }