public static void ReseedNpcOfferedOrders() { var order_data = Game1.content.Load <Dictionary <string, SpecialOrderData> >("Data\\SpecialOrders"); List <string> keys = GatherValidOrderKeys(order_data); Random r = new Random((int)Game1.uniqueIDForThisGame + (int)((float)Game1.stats.DaysPlayed * 1.3f)); // Clean NPC offers before new seed for (int i = 0; i < Game1.player.team.availableSpecialOrders.Count; i++) { var toRemove = Game1.player.team.availableSpecialOrders[i]; if (toRemove.orderType.Value == "QF_NPC") { Game1.player.team.availableSpecialOrders.RemoveAt(i); i--; } } foreach (string key in keys) { if (!order_data.ContainsKey(key)) { continue; } if (order_data[key].OrderType == "QF_NPC") { Game1.player.team.availableSpecialOrders.Add(SpecialOrder.GetSpecialOrder(key, r.Next())); } } }
public override void receiveLeftClick(int x, int y, bool playSound = true) { base.receiveLeftClick(x, y, playSound); if (acceptLeftQuestButton.visible && acceptLeftQuestButton.containsPoint(x, y)) { Game1.playSound("newArtifact"); if (leftOrder != null) { Game1.player.team.acceptedSpecialOrderTypes.Add(GetOrderType()); SpecialOrder order2 = leftOrder; Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(order2.questKey.Value, order2.generationSeed)); Game1.multiplayer.globalChatInfoMessage("AcceptedSpecialOrder", Game1.player.Name, order2.GetName()); UpdateButtons(); } } else if (acceptRightQuestButton.visible && acceptRightQuestButton.containsPoint(x, y)) { Game1.playSound("newArtifact"); if (rightOrder != null) { Game1.player.team.acceptedSpecialOrderTypes.Add(GetOrderType()); SpecialOrder order = rightOrder; Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(order.questKey.Value, order.generationSeed)); Game1.multiplayer.globalChatInfoMessage("AcceptedSpecialOrder", Game1.player.Name, order.GetName()); UpdateButtons(); } } }
static void OnEventFinished(object sender, EventArgs e) { if (!Game1.player.IsMainPlayer) { return; } switch (Game1.CurrentEvent.id) { case MEETBELINDA: TryRemoveQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); // Added in line 137, might also have been completed upon reading ninja note TryCompleteQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); // Added in QF hooks currently TryAddQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); break; case PREUNSEAL: TryCompleteQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); // Crystal quests are then added break; case BLISSVISIT: // Comes after crystal quests are complete TryAddQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); break; case RAEUNSEAL: TryCompleteQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); TryAddQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); break; case OPENPORTAL: TryCompleteQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); if (Game1.player.IsMainPlayer) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder("RSV.UntimedSpecialOrder.SpiritRealmFlames", null)); } break; case BLISSGH1: TryAddQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); break; case SPIRITGH1: TryCompleteQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); break; case BLISSGH2: TryAddQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); break; case SPIRITGH2: TryCompleteQuest(ExternalAPIs.QF.ResolveQuestId("*****@*****.**")); // Greenhouse quest then added break; } }
/// <summary>Loads 2 orders of the provided order type if possible.</summary> /// <remarks>Imitates logic from <see cref="SpecialOrder.UpdateAvailableSpecialOrders(bool)"/> to load the provided order type. Note that the original only loads "" and "Qi" types.</remarks> /// <param name="customOrderType">The <see cref="SpecialOrder.orderType"/> to load.</param> /// <param name="order_data">Loaded data from the asset "Data/SpecialOrders".</param> /// <param name="keys">Valid keys for available orders. See <see cref="GetAvailableOrderKeys"/>.</param> private static void LoadCustomOrderType(string customOrderType, Dictionary <string, SpecialOrderData> order_data, List <string> keys) { if (Game1.player.team.availableSpecialOrders.Any(order => order.orderType.Value == customOrderType)) //if any available orders already have this type { return; //do nothing } //imitate the original update method's loading logic, but load 2 orders of the custom type //note that comments below indicate edited code (actual comments) or removed code (commented out) Random r = new Random((int)Game1.uniqueIDForThisGame + (int)((float)Game1.stats.DaysPlayed * 1.3f)); //Game1.player.team.availableSpecialOrders.Clear(); //string[] array = new string[2]{ "", "Qi" }; //foreach (string type_to_find in array) //{ List <string> typed_keys = new List <string>(); foreach (string key3 in keys) { if (order_data[key3].OrderType == customOrderType) //replace type_to_find with customOrderType { typed_keys.Add(key3); } } List <string> all_keys = new List <string>(typed_keys); //if (type_to_find != "Qi") //{ for (int j = 0; j < typed_keys.Count; j++) { if (Game1.player.team.completedSpecialOrders.ContainsKey(typed_keys[j])) { typed_keys.RemoveAt(j); j--; } } //} for (int i = 0; i < 2; i++) { if (typed_keys.Count == 0) { if (all_keys.Count == 0) { break; } typed_keys = new List <string>(all_keys); } int index = r.Next(typed_keys.Count); string key2 = typed_keys[index]; Game1.player.team.availableSpecialOrders.Add(SpecialOrder.GetSpecialOrder(key2, r.Next())); //prefix GetSpecialOrder with the SpecialOrder class (normally called internally) typed_keys.Remove(key2); all_keys.Remove(key2); } //} }
public static void SeedCustomAvailableSpecialOrders(string[] validTypes, int pick = 2) { var order_data = Game1.content.Load <Dictionary <string, SpecialOrderData> >("Data\\SpecialOrders"); List <string> keys = GatherValidOrderKeys(order_data); Random r = new Random((int)Game1.uniqueIDForThisGame + (int)((float)Game1.stats.DaysPlayed * 1.3f)); foreach (string type_to_find in validTypes) { var typed_keys = new List <string>(); foreach (string key3 in keys) { if (order_data[key3].OrderType == type_to_find) { typed_keys.Add(key3); } } if (type_to_find != "Qi") { for (int j = 0; j < typed_keys.Count; j++) { if (Game1.player.team.completedSpecialOrders.ContainsKey(typed_keys[j])) { typed_keys.RemoveAt(j); j--; } } } var all_keys = new List <string>(typed_keys); for (int i = 0; i < pick; i++) { if (typed_keys.Count == 0) { if (all_keys.Count == 0) { break; } typed_keys = new List <string>(all_keys); } int index = r.Next(typed_keys.Count); string key2 = typed_keys[index]; Game1.player.team.availableSpecialOrders.Add(SpecialOrder.GetSpecialOrder(key2, r.Next())); typed_keys.Remove(key2); all_keys.Remove(key2); } } }
private static void UpdateSpecialOrders() { foreach (var entry in EventsAndSpecialOrders) //for each entry in the event dictionary { foreach (Farmer farmer in Game1.getAllFarmers()) //for each existing player { if (farmer.eventsSeen.Contains(entry.Key)) //if a player has seen this entry's event ID { foreach (string orderName in entry.Value) //for each special order that should be added { if (!Game1.player.team.SpecialOrderActive(orderName) && //if the players do NOT currently have this order !Game1.player.team.completedSpecialOrders.ContainsKey(orderName)) //AND if the players have NOT completed this order before { SpecialOrder order = SpecialOrder.GetSpecialOrder(orderName, null); //create this order Game1.player.team.specialOrders.Add(order); //add it to the players' log } } break; //skip the rest of the player checks for this entry } } } }
private static void OnUpdate(object sender, OneSecondUpdateTickedEventArgs e) { if (Game1.player.eventsSeen.Contains(75160190) && !Game1.player.team.SpecialOrderActive(FIXMINECART) && !Game1.player.team.completedSpecialOrders.ContainsKey(FIXMINECART)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(FIXMINECART, null)); } if (Game1.player.eventsSeen.Contains(75160089) && !Game1.player.team.SpecialOrderActive(FIXGREENHOUSE) && !Game1.player.team.completedSpecialOrders.ContainsKey(FIXGREENHOUSE)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(FIXGREENHOUSE, null)); } if (Game1.player.eventsSeen.Contains(75160254) && !Game1.player.team.SpecialOrderActive(DAIAQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(DAIAQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(DAIAQUEST, null)); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(RedCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(RedCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(RedCRYSTALQUEST, null)); Game1.player.mailReceived.Add("CrystalsFlagOngoing"); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(OrangeCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(OrangeCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(OrangeCRYSTALQUEST, null)); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(YellowCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(YellowCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(YellowCRYSTALQUEST, null)); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(GreenCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(GreenCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(GreenCRYSTALQUEST, null)); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(BlueCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(BlueCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(BlueCRYSTALQUEST, null)); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(PurpleCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(PurpleCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(PurpleCRYSTALQUEST, null)); } if (Game1.player.eventsSeen.Contains(75160257) && !Game1.player.team.SpecialOrderActive(GrayCRYSTALQUEST) && !Game1.player.team.completedSpecialOrders.ContainsKey(GrayCRYSTALQUEST)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(GrayCRYSTALQUEST, null)); } //Specific code to give message to player upon finishing crystals quest if (Game1.player.team.completedSpecialOrders.ContainsKey(RedCRYSTALQUEST) && Game1.player.team.completedSpecialOrders.ContainsKey(OrangeCRYSTALQUEST) && Game1.player.team.completedSpecialOrders.ContainsKey(YellowCRYSTALQUEST) && Game1.player.team.completedSpecialOrders.ContainsKey(GreenCRYSTALQUEST) && Game1.player.team.completedSpecialOrders.ContainsKey(BlueCRYSTALQUEST) && Game1.player.team.completedSpecialOrders.ContainsKey(PurpleCRYSTALQUEST) && Game1.player.team.completedSpecialOrders.ContainsKey(GrayCRYSTALQUEST) && Game1.player.mailReceived.Contains("CrystalsFlagOngoing")) { Game1.player.mailReceived.Remove("CrystalsFlagOngoing"); Game1.playSound("healSound"); Game1.activeClickableMenu = new DialogueBox(Helper.Translation.Get("CompleteCrystalsNotif")); } if (Game1.player.eventsSeen.Contains(75160269) && !Game1.player.team.SpecialOrderActive(HAUNTEDGH) && !Game1.player.team.completedSpecialOrders.ContainsKey(HAUNTEDGH)) { Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(HAUNTEDGH, null)); } }
/// <summary>Updates players' quest logs to add/remove each entry in <see cref="SpecialOrders"/>, depending on whether their conditions are met.</summary> private static void UpdateSpecialOrders() { foreach (var entry in SpecialOrders) //for each entry in the special orders list { List <int> seenEvents; List <int> notSeenEvents; try { //try to parse this order's conditions seenEvents = ParseEventsString(entry.HasSeenEvents); notSeenEvents = ParseEventsString(entry.HasNotSeenEvents); } catch (Exception ex) //if the conditions couldn't be parsed { Monitor.Log($"Failed to parse event ID lists for this special order: \"{entry.OrderKey}\". The order won't be added/removed until this error is fixed. Full error message: \n{ex.ToString()}", LogLevel.Error); continue; //skip to the next order } bool allConditionsMet = true; //true if players meet all the required conditions for this order //prepare log message data string unmetSeenEvents = ""; string unmetNotSeenEvents = ""; foreach (int seenEvent in seenEvents) //for each event the players must have seen { if (Game1.getAllFarmers().Any(farmer => farmer.eventsSeen.Contains(seenEvent)) == false) //if NO players have seen this event { unmetSeenEvents += $" {seenEvent}"; allConditionsMet = false; } } foreach (int notSeenEvent in notSeenEvents) //for each event the players must NOT have seen { if (Game1.getAllFarmers().Any(farmer => farmer.eventsSeen.Contains(notSeenEvent)) == true) //if any player has seen this event { unmetNotSeenEvents += $" {notSeenEvent}"; allConditionsMet = false; } } if (allConditionsMet && Game1.player.team.completedSpecialOrders.ContainsKey(entry.OrderKey) == false) //if conditions are met AND the players have NOT completed this order { if (Game1.player.team.SpecialOrderActive(entry.OrderKey) == false) //if the players do not already have this order { Monitor.Log($"Adding special order \"{entry.OrderKey}\" to quest logs. All conditions met; order has not been completed yet.", LogLevel.Trace); SpecialOrder order = SpecialOrder.GetSpecialOrder(entry.OrderKey, null); //create this order Game1.player.team.specialOrders.Add(order); //add it to the players' quest logs } } else //if conditions are NOT met OR players have completed this order { for (int x = Game1.player.team.specialOrders.Count - 1; x >= 0; x--) //for each of the players' special orders (looping backward for easier removal) { SpecialOrder order = Game1.player.team.specialOrders[x]; //get the current order if (order.questKey.Value.Equals(entry.OrderKey) && //if this is the same order order.questState.Value == SpecialOrder.QuestState.InProgress) //AND this order is currently active { Monitor.Log($"Removing special order \"{entry.OrderKey}\" from quest logs. Reason(s):", LogLevel.Trace); if (unmetSeenEvents?.Length > 0 || unmetNotSeenEvents.Length > 0) //if any conditions were unmet { Monitor.Log($" Unmet \"HasSeenEvent\" conditions:{unmetSeenEvents}", LogLevel.Trace); Monitor.Log($" Unmet \"HasNotSeenEvent\" conditions:{unmetNotSeenEvents}", LogLevel.Trace); } else //if no unmet conditions were documented (i.e. this was removed because it was completed already) { Monitor.Log($" All conditions met; order may have already been completed.", LogLevel.Trace); } order.OnFail(); //perform "failure" behaviors before removal, e.g. refunding resources Game1.player.team.specialOrders.RemoveAt(x); //remove the order from the players' quest logs } } } } }
private static bool Before_checkAction(NPC __instance, Farmer who, ref bool __result) { try { if (Game1.eventUp || __instance.IsInvisible || __instance.isSleeping.Value || !who.CanMove || who.isRidingHorse()) { return(true); } if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift() && !who.isRidingHorse()) { return(true); } if (Game1.dialogueUp) { return(true); } Instance.QuestManager.AdjustQuest(new TalkMessage(who, __instance)); if (Game1.dialogueUp && Game1.currentSpeaker == __instance) { __result = true; return(false); } Instance.Monitor.VerboseLog($"Checking for new quest from NPC `{__instance.Name}`."); if (Instance.OfferController.TryOfferNpcQuest(__instance, out QuestOffer <NpcOfferAttributes> offer)) { __result = true; Game1.drawDialogue(__instance, $"{offer.OfferDetails.DialogueText}[quest:{offer.QuestName.Replace('@', ' ')}]"); QuestFrameworkMod.Instance.Monitor.Log($"Getting new quest `{offer.QuestName}` to quest log from NPC `{__instance.Name}`."); return(false); } if (Instance.OfferController.TryOfferNpcSpecialOrder(__instance, out SpecialOrder specialOrder)) { if (!__instance.Dialogue.TryGetValue($"offerOrder_{specialOrder.questKey.Value}", out string dialogue)) { dialogue = specialOrder.GetDescription(); } __result = true; Game1.player.team.specialOrders.Add(SpecialOrder.GetSpecialOrder(specialOrder.questKey.Value, specialOrder.generationSeed.Value)); Game1.addHUDMessage(new HUDMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Farmer.cs.2011"), 2)); Game1.drawDialogue(__instance, dialogue); QuestFrameworkMod.Multiplayer.globalChatInfoMessage("AcceptedSpecialOrder", Game1.player.Name, specialOrder.GetName()); Instance.OfferController.RefreshActiveIndicators(); return(false); } } catch (Exception e) { Instance.LogFailure(e, nameof(Instance.Before_checkAction)); } return(true); }
public static void UpdateAvailableSpecialOrders(string[] validTypes) { SpecialOrder.UpdateAvailableSpecialOrders(true); var order_data = Game1.content.Load <Dictionary <string, SpecialOrderData> >("Data\\SpecialOrders"); var keys = new List <string>(order_data.Keys); for (int k = 0; k < keys.Count; k++) { string key = keys[k]; bool invalid = false; if (!invalid && order_data[key].Repeatable != "True" && Game1.MasterPlayer.team.completedSpecialOrders.ContainsKey(key)) { invalid = true; } if (Game1.dayOfMonth >= 16 && order_data[key].Duration == "Month") { invalid = true; } if (!invalid && !SpecialOrder.CheckTags(order_data[key].RequiredTags)) { invalid = true; } if (!invalid) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { if (specialOrder.questKey.Value == key) { invalid = true; break; } } } if (invalid) { keys.RemoveAt(k); k--; } } Random r = new Random((int)Game1.uniqueIDForThisGame + (int)((float)Game1.stats.DaysPlayed * 1.3f)); foreach (string type_to_find in validTypes) { var typed_keys = new List <string>(); foreach (string key3 in keys) { if (order_data[key3].OrderType == type_to_find) { typed_keys.Add(key3); } } if (type_to_find != "Qi") { for (int j = 0; j < typed_keys.Count; j++) { if (Game1.player.team.completedSpecialOrders.ContainsKey(typed_keys[j])) { typed_keys.RemoveAt(j); j--; } } } var all_keys = new List <string>(typed_keys); for (int i = 0; i < 2; i++) { if (typed_keys.Count == 0) { if (all_keys.Count == 0) { break; } typed_keys = new List <string>(all_keys); } int index = r.Next(typed_keys.Count); string key2 = typed_keys[index]; Game1.player.team.availableSpecialOrders.Add(SpecialOrder.GetSpecialOrder(key2, r.Next())); typed_keys.Remove(key2); all_keys.Remove(key2); } } }