/// <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 } } } } }