public SchedulePathDescriptionWrapper(SchedulePathDescription item) => GetBaseType = item;
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }