public SchedulePathDescriptionWrapper(SchedulePathDescription item) => GetBaseType = item;
private Dictionary <int, SchedulePathDescription> MasterScheduleParse(string scheduleString) { NPC companion = this.StateMachine.Companion; int timeOfDay = Game1.timeOfDay; string[] split = scheduleString.Split(new char[] { '/' }); Dictionary <int, SchedulePathDescription> oneDaySchedule = new Dictionary <int, SchedulePathDescription>(); Type[] pathfinderTypes = new Type[] { typeof(string), typeof(int), typeof(int), typeof(string), typeof(int), typeof(int), typeof(int), typeof(string), typeof(string) }; MethodInfo pathfinder = typeof(NPC).GetMethod("pathfindToNextScheduleLocation", BindingFlags.NonPublic | BindingFlags.Instance, null, pathfinderTypes, null); int routesToSkip = 0; int previousTime = 0; if (split[0].Contains("GOTO")) { string newKey = split[0].Split(new char[] { ' ' })[1]; if (newKey.ToLower().Equals("season")) { newKey = Game1.currentSeason; } try { split = Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name) [newKey].Split(new char[] { '/' }); } catch (Exception) { return(this.MasterScheduleParse( Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name)[ "spring"])); } } if (split[0].Contains("NOT")) { string[] commandSplit = split[0].Split(new char[] { ' ' }); string a = commandSplit[1].ToLower(); if (a == "friendship") { string who = commandSplit[2]; int level = Convert.ToInt32(commandSplit[3]); bool conditionMet = false; using (IEnumerator <Farmer> enumerator = Game1.getAllFarmers().GetEnumerator()) { while (enumerator.MoveNext()) { if (enumerator.Current.getFriendshipLevelForNPC(who) >= level) { conditionMet = true; break; } } } if (conditionMet) { return(this.MasterScheduleParse(Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name)["spring"])); } routesToSkip++; } } else if (split[0].Contains("MAIL")) { string id = split[0].Split(' ')[1]; if (Game1.MasterPlayer.mailReceived.Contains(id) || NetWorldState.checkAnywhereForWorldStateID(id)) { routesToSkip += 2; } else { routesToSkip++; } } if (split[routesToSkip].Contains("GOTO")) { string newKey2 = split[routesToSkip].Split(new char[] { ' ' })[1]; if (newKey2.ToLower().Equals("season")) { newKey2 = Game1.currentSeason; } return(this.MasterScheduleParse(Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name)[newKey2])); } Point previousPosition = companion.isMarried() ? new Point(0, 23) : new Point((int)companion.DefaultPosition.X / 64, (int)companion.DefaultPosition.Y / 64); string previousGameLocation = companion.isMarried() ? "BusStop" : companion.DefaultMap; int i = routesToSkip; while (i < split.Length && split.Length > 1) { int index = 0; string[] newDestinationDescription = split[i].Split(new char[] { ' ' }); int time = Convert.ToInt32(newDestinationDescription[index]); index++; string location = newDestinationDescription[index]; string endOfRouteAnimation = null; string endOfRouteMessage = null; if (int.TryParse(location, out int tmp)) { location = previousGameLocation; index--; } index++; int xLocation = Convert.ToInt32(newDestinationDescription[index]); index++; int yLocation = Convert.ToInt32(newDestinationDescription[index]); index++; int localFacingDirection = 2; try { localFacingDirection = Convert.ToInt32(newDestinationDescription[index]); index++; } catch (Exception) { localFacingDirection = 2; } if (this.changeScheduleForLocationAccessibility(ref location, ref xLocation, ref yLocation, ref localFacingDirection)) { if (Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name).ContainsKey("default")) { return(this.MasterScheduleParse(Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name)["default"])); } return(this.MasterScheduleParse(Game1.content.Load <Dictionary <string, string> >("Characters\\schedules\\" + companion.Name)["spring"])); } else { if (index < newDestinationDescription.Length) { if (newDestinationDescription[index].Length > 0 && newDestinationDescription[index][0] == '"') { endOfRouteMessage = split[i].Substring(split[i].IndexOf('"')).Replace("\"", ""); } else { endOfRouteAnimation = newDestinationDescription[index]; index++; if (index < newDestinationDescription.Length && newDestinationDescription[index].Length > 0 && newDestinationDescription[index][0] == '"') { endOfRouteMessage = split[i].Substring(split[i].IndexOf('"')).Replace("\"", ""); } } } object[] parameters = new object[] { previousGameLocation, previousPosition.X, previousPosition.Y, location, xLocation, yLocation, localFacingDirection, endOfRouteAnimation, endOfRouteMessage }; SchedulePathDescription schedulePathDesc = (SchedulePathDescription)pathfinder.Invoke(companion, parameters); oneDaySchedule.Add(time, schedulePathDesc); previousPosition.X = xLocation; previousPosition.Y = yLocation; if (timeOfDay >= time && schedulePathDesc.route != null && schedulePathDesc.route.Count != 0) { Stack <Point> sp = oneDaySchedule[time].route; Point p = new Point(); while (sp.Count > 1) { sp.Pop(); } while (sp.Count != 0) { p = sp.Pop(); } if (previousTime < time) { this.companionRescheduleDestinationPoint = p; this.companionRescheduleDestinationLocation = location; this.companionRescheduleEndRouteBehavior = endOfRouteAnimation; this.companionRescheduleEndRouteDialogue = endOfRouteMessage; this.companionRescheduleFacingDirection = localFacingDirection; } } previousTime = time; previousGameLocation = location; i++; } } return(oneDaySchedule); }
public static bool Prefix(NPC __instance, int timeOfDay, ref Point ___previousEndPoint, ref string ___extraDialogueMessageToAddThisMorning, ref SchedulePathDescription ___directionsToNewLocation, ref Rectangle ___lastCrossroad, ref NetString ___endOfRouteBehaviorName) { if (!ModEntry.IsChildNPC(__instance)) { return(true); } __instance.updatedDialogueYet = false; ___extraDialogueMessageToAddThisMorning = null; if (__instance.ignoreScheduleToday || __instance.Schedule == null) { return(false); } __instance.Schedule.TryGetValue(__instance.scheduleTimeToTry == 9999999 ? timeOfDay : __instance.scheduleTimeToTry, out SchedulePathDescription schedulePathDescription); //If I have curfew, override the normal behavior if (ModEntry.Config.DoChildrenHaveCurfew && !__instance.currentLocation.Equals(Game1.getLocationFromName("FarmHouse"))) { //Send child home for curfew if (timeOfDay == ModEntry.Config.CurfewTime) { object[] pathfindParams = { __instance.currentLocation.Name, __instance.getTileX(), __instance.getTileY(), "BusStop", -1, 23, 3, null, null }; schedulePathDescription = ModEntry.helper.Reflection.GetMethod(__instance, "pathfindToNextScheduleLocation", true).Invoke <SchedulePathDescription>(pathfindParams); } //Ignore scheduled events after curfew else if (timeOfDay > ModEntry.Config.CurfewTime) { schedulePathDescription = null; } } if (schedulePathDescription == null) { return(false); } //Normally I would see a IsMarried check here, but FarmHouse may be better? //(I think this section is meant for handling when the character is still walking) if (!__instance.currentLocation.Equals(Game1.getLocationFromName("FarmHouse")) || !__instance.IsWalkingInSquare || ___lastCrossroad.Center.X / 64 != ___previousEndPoint.X && ___lastCrossroad.Y / 64 != ___previousEndPoint.Y) { if (!___previousEndPoint.Equals(Point.Zero) && !___previousEndPoint.Equals(__instance.getTileLocationPoint())) { if (__instance.scheduleTimeToTry == 9999999) { __instance.scheduleTimeToTry = timeOfDay; } return(false); } } ___directionsToNewLocation = schedulePathDescription; //__instance.prepareToDisembarkOnNewSchedulePath(); ModEntry.helper.Reflection.GetMethod(__instance, "prepareToDisembarkOnNewSchedulePath", true).Invoke(null); if (__instance.Schedule == null) { return(false); } if (___directionsToNewLocation != null && ___directionsToNewLocation.route != null && ___directionsToNewLocation.route.Count > 0 && (Math.Abs(__instance.getTileLocationPoint().X - ___directionsToNewLocation.route.Peek().X) > 1 || Math.Abs(__instance.getTileLocationPoint().Y - ___directionsToNewLocation.route.Peek().Y) > 1) && __instance.temporaryController == null) { __instance.scheduleTimeToTry = 9999999; return(false); } __instance.controller = new PathFindController(___directionsToNewLocation.route, __instance, Utility.getGameLocationOfCharacter(__instance)) { finalFacingDirection = ___directionsToNewLocation.facingDirection, //endBehaviorFunction = this.getRouteEndBehaviorFunction(this.directionsToNewLocation.endOfRouteBehavior, this.directionsToNewLocation.endOfRouteMessage) endBehaviorFunction = ModEntry.helper.Reflection.GetMethod(__instance, "getRouteEndBehaviorFunction", true).Invoke <PathFindController.endBehavior>(new object[] { __instance.DirectionsToNewLocation.endOfRouteBehavior, __instance.DirectionsToNewLocation.endOfRouteMessage }) }; __instance.scheduleTimeToTry = 9999999; if (___directionsToNewLocation != null && ___directionsToNewLocation.route != null) { ___previousEndPoint = ___directionsToNewLocation.route.Count > 0 ? ___directionsToNewLocation.route.Last() : Point.Zero; } return(false); }