예제 #1
0
    /// <summary>
    /// Generates schedules for everyone.
    /// </summary>
    internal static void GenerateAllSchedules()
    {
        Game1.netWorldState.Value.IslandVisitors.Clear();
        if (Game1.getLocationFromName("IslandSouth") is not IslandSouth island || !island.resortRestored.Value ||
            !island.resortOpenToday.Value || Game1.IsRainingHere(island) ||
            Utility.isFestivalDay(Game1.Date.DayOfMonth, Game1.Date.Season) ||
            (Game1.Date.DayOfMonth >= 15 && Game1.Date.DayOfMonth <= 17 && Game1.IsWinter))
        {
            return;
        }

        Random random = new((int)(Game1.uniqueIDForThisGame * 1.21f) + (int)(Game1.stats.DaysPlayed * 2.5f));

        HashSet <NPC> explorers = GenerateExplorerGroup(random);

        if (explorers.Count > 0)
        {
            Globals.ModMonitor.DebugOnlyLog($"Found explorer group: {string.Join(", ", explorers.Select((NPC npc) => npc.Name))}.");
            IslandNorthScheduler.Schedule(random, explorers);
        }

        // Resort capacity set to zero, can skip everything else.
        if (Globals.Config.Capacity == 0 && (Globals.SaveDataModel is null || Globals.SaveDataModel.NPCsForTomorrow.Count == 0))
        {
            IslandSouthPatches.ClearCache();
            GIScheduler.ClearCache();
            return;
        }

        List <NPC> visitors = GenerateVistorList(random, Globals.Config.Capacity, explorers);
        Dictionary <string, string> animationDescriptions = Globals.ContentHelper.Load <Dictionary <string, string> >("Data/animationDescriptions", ContentSource.GameContent);

        GIScheduler.Bartender = SetBartender(visitors);
        GIScheduler.Musician  = SetMusician(random, visitors, animationDescriptions);

        List <GingerIslandTimeSlot> activities = AssignIslandSchedules(random, visitors, animationDescriptions);
        Dictionary <NPC, string>    schedules  = RenderIslandSchedules(random, visitors, activities);

        foreach (NPC visitor in schedules.Keys)
        {
            Globals.ModMonitor.Log($"Calculated island schedule for {visitor.Name}");
            visitor.islandScheduleName.Value = "island";

            ScheduleUtilities.ParseMasterScheduleAdjustedForChild2NPC(visitor, schedules[visitor]);

            Game1.netWorldState.Value.IslandVisitors[visitor.Name] = true;
            ConsoleCommands.IslandSchedules[visitor.Name]          = schedules[visitor];
        }

        IslandSouthPatches.ClearCache();
        GIScheduler.ClearCache();

#if DEBUG
        Globals.ModMonitor.Log($"Current memory usage {GC.GetTotalMemory(false):N0}", LogLevel.Alert);
        GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
        GC.Collect();
        Globals.ModMonitor.Log($"Post-collection memory usage {GC.GetTotalMemory(true):N0}", LogLevel.Alert);
#endif
    }
예제 #2
0
    private void OnTimeChanged(object?sender, TimeChangedEventArgs e)
    {
        MidDayScheduleEditor.AttemptAdjustGISchedule(e);
        if (e.NewTime > 615 && !this.haveFixedSchedulesToday)
        {
            // No longer need the exclusions cache.
            IslandSouthPatches.ClearCache();

            ScheduleUtilities.FixUpSchedules();
            if (Globals.Config.DebugMode)
            {
                ScheduleDebugPatches.FixNPCs();
            }
            this.haveFixedSchedulesToday = true;
        }
    }
예제 #3
0
    /// <summary>
    /// Clear all caches at the end of the day and if the player exits to menu.
    /// </summary>
    private void ClearCaches()
    {
        DialoguePatches.ClearTalkRecord();
        DialogueUtilities.ClearDialogueLog();

        if (Context.IsSplitScreen && Context.ScreenId != 0)
        {
            return;
        }
        this.haveFixedSchedulesToday = false;
        MidDayScheduleEditor.Reset();
        IslandSouthPatches.ClearCache();
        GIScheduler.ClearCache();
        GIScheduler.DayEndReset();
        ConsoleCommands.ClearCache();
        ScheduleUtilities.ClearCache();
    }
예제 #4
0
    /// <summary>
    /// Takes a list of activities and renders them as proper schedules.
    /// </summary>
    /// <param name="random">Sedded random.</param>
    /// <param name="visitors">List of visitors.</param>
    /// <param name="activities">List of activities.</param>
    /// <returns>Dictionary of NPC->raw schedule strings.</returns>
    private static Dictionary <NPC, string> RenderIslandSchedules(Random random, List <NPC> visitors, List <GingerIslandTimeSlot> activities)
    {
        Dictionary <NPC, string> completedSchedules = new();

        foreach (NPC visitor in visitors)
        {
            bool should_dress = IslandSouth.HasIslandAttire(visitor);
            List <SchedulePoint> scheduleList = new();

            if (should_dress)
            {
                scheduleList.Add(new SchedulePoint(
                                     random: random,
                                     npc: visitor,
                                     map: "IslandSouth",
                                     time: 1150,
                                     point: IslandSouth.GetDressingRoomPoint(visitor),
                                     animation: "change_beach",
                                     isarrivaltime: true));
            }

            foreach (GingerIslandTimeSlot activity in activities)
            {
                if (activity.Assignments.TryGetValue(visitor, out SchedulePoint? schedulePoint))
                {
                    scheduleList.Add(schedulePoint);
                }
            }

            if (should_dress)
            {
                scheduleList.Add(new SchedulePoint(
                                     random: random,
                                     npc: visitor,
                                     map: "IslandSouth",
                                     time: 1730,
                                     point: IslandSouth.GetDressingRoomPoint(visitor),
                                     animation: "change_normal",
                                     isarrivaltime: true));
            }

            scheduleList[0].IsArrivalTime = true; // set the first slot, whatever it is, to be the arrival time.

            // render the schedule points to strings before appending the remainder schedules
            // which are already strings.
            List <string> schedPointString = scheduleList.Select((SchedulePoint pt) => pt.ToString()).ToList();
            if (visitor.Name.Equals("Gus", StringComparison.OrdinalIgnoreCase))
            {
                // Gus needs to tend bar. Hardcoded same as vanilla.
                schedPointString.Add("1800 Saloon 10 18 2/2430 bed");
            }
            else
            {
                // Try to find a GI remainder schedule, if any.
                schedPointString.Add(ScheduleUtilities.FindProperGISchedule(visitor, SDate.Now())
                                     // Child2NPC NPCs don't understand "bed", must send them to the bus stop spouse dropoff.
                                     ?? (Globals.IsChildToNPC?.Invoke(visitor) == true ? "1800 BusStop -1 23 3" : "1800 bed"));
            }
            completedSchedules[visitor] = string.Join("/", schedPointString);
            Globals.ModMonitor.DebugOnlyLog($"For {visitor.Name}, created island schedule {completedSchedules[visitor]}");
        }
        return(completedSchedules);
    }
 public BreakAvailabilityUpdateHandler(ILogger logger, IBreakRepository breakRepository, Schedule schedule)
 {
     _logger            = logger ?? throw new ArgumentNullException(nameof(logger));
     _breakRepository   = breakRepository ?? throw new ArgumentNullException(nameof(breakRepository));
     _scheduleUtilities = CreateScheduleUtilities(schedule);
 }