コード例 #1
0
ファイル: AreaData.cs プロジェクト: jakobrs/Everest
        public static new void Load()
        {
            orig_Load();

            // assign SIDs and CheckpointData.Area for vanilla maps.
            foreach (AreaData area in Areas)
            {
                area.SetSID("Celeste/" + area.Mode[0].Path);

                for (int modeId = 0; modeId < area.Mode.Length; modeId++)
                {
                    ModeProperties mode = area.Mode[modeId];
                    if (mode?.Checkpoints == null)
                    {
                        continue;
                    }

                    foreach (CheckpointData checkpoint in mode.Checkpoints)
                    {
                        checkpoint.SetArea(area.ToKey((AreaMode)modeId));
                    }
                }
            }

            // Separate array as we sort it afterwards.
            List <AreaData> modAreas = new List <AreaData>();

            lock (Everest.Content.Map) {
                foreach (ModAsset asset in Everest.Content.Map.Values.Where(asset => asset.Type == typeof(AssetTypeMap)))
                {
                    string path = asset.PathVirtual.Substring(5);

                    AreaData area = new AreaData();

                    // Default values.

                    area.SetSID(path);
                    area.Name = path;
                    area.Icon = "areas/" + path.ToLowerInvariant();
                    if (!GFX.Gui.Has(area.Icon))
                    {
                        area.Icon = "areas/null";
                    }

                    area.Interlude    = false;
                    area.CanFullClear = true;

                    area.TitleBaseColor   = Calc.HexToColor("6c7c81");
                    area.TitleAccentColor = Calc.HexToColor("2f344b");
                    area.TitleTextColor   = Color.White;

                    area.IntroType = Player.IntroTypes.WakeUp;

                    area.Dreaming   = false;
                    area.ColorGrade = null;

                    area.Mode = new ModeProperties[] {
                        new ModeProperties {
                            Inventory  = PlayerInventory.Default,
                            AudioState = new AudioState(SFX.music_city, SFX.env_amb_00_main)
                        }
                    };

                    area.Wipe = (Scene scene, bool wipeIn, Action onComplete)
                                => new AngledWipe(scene, wipeIn, onComplete);

                    area.DarknessAlpha = 0.05f;
                    area.BloomBase     = 0f;
                    area.BloomStrength = 1f;

                    area.Jumpthru = "wood";

                    area.CassseteNoteColor = Calc.HexToColor("33a9ee");
                    area.CassetteSong      = SFX.cas_01_forsaken_city;

                    // Custom values can be set via the MapMeta.
                    MapMeta meta = new MapMeta();
                    meta.ApplyTo(area);
                    MapMeta metaLoaded = asset.GetMeta <MapMeta>();
                    if (metaLoaded != null)
                    {
                        area.SetMeta(null);
                        metaLoaded.ApplyTo(area);
                        meta = metaLoaded;
                    }

                    if (string.IsNullOrEmpty(area.Mode[0].Path))
                    {
                        area.Mode[0].Path = asset.PathVirtual.Substring(5);
                    }

                    // Some of the game's code checks for [1] / [2] explicitly.
                    // Let's just provide null modes to fill any gaps.
                    meta.Modes = meta.Modes ?? new MapMetaModeProperties[3];
                    if (meta.Modes.Length < 3)
                    {
                        MapMetaModeProperties[] larger = new MapMetaModeProperties[3];
                        for (int i = 0; i < meta.Modes.Length; i++)
                        {
                            larger[i] = meta.Modes[i];
                        }
                        meta.Modes = larger;
                    }
                    if (area.Mode.Length < 3)
                    {
                        ModeProperties[] larger = new ModeProperties[3];
                        for (int i = 0; i < area.Mode.Length; i++)
                        {
                            larger[i] = area.Mode[i];
                        }
                        area.Mode = larger;
                    }

                    // Celeste levelset always appears first.
                    if (area.GetLevelSet() == "Celeste")
                    {
                        Areas.Add(area);
                    }
                    else
                    {
                        modAreas.Add(area);
                    }

                    // Some special handling.
                    area.OnLevelBegin = (level) => {
                        MapMeta levelMeta = AreaData.Get(level.Session).GetMeta();
                        MapMetaModeProperties levelMetaMode = level.Session.MapData.GetMeta();

                        if (levelMetaMode?.SeekerSlowdown ?? false)
                        {
                            level.Add(new SeekerEffectsController());
                        }
                    };
                }
            }


            // Merge modAreas into Areas.
            Areas.AddRange(modAreas);

            // Find duplicates and remove any earlier copies.
            for (int i = 0; i < Areas.Count; i++)
            {
                AreaData area       = Areas[i];
                int      otherIndex = Areas.FindIndex(other => other.GetSID() == area.GetSID());
                if (otherIndex < i)
                {
                    Areas[otherIndex] = area;
                    Areas.RemoveAt(i);
                    i--;
                }
            }

            // Sort areas.
            Areas.Sort(AreaComparison);

            // Remove AreaDatas which are now a mode of another AreaData.
            // This can happen late as the map data (.bin) can contain additional metadata.
            for (int i = 0; i < Areas.Count; i++)
            {
                AreaData area       = Areas[i];
                string   path       = area.Mode[0].Path;
                int      otherIndex = Areas.FindIndex(other => other.Mode.Any(otherMode => otherMode?.Path == path));
                if (otherIndex != -1 && otherIndex != i)
                {
                    Areas.RemoveAt(i);
                    i--;
                    continue;
                }

                int?     order;
                AreaMode side;
                string   name;
                ParseName(path, out order, out side, out name);

                // Also check for .bins possibly belonging to A side .bins by their path and lack of existing modes.
                for (int ii = 0; ii < Areas.Count; ii++)
                {
                    AreaData other = Areas[ii];
                    int?     otherOrder;
                    AreaMode otherSide;
                    string   otherName;
                    ParseName(other.Mode[0].Path, out otherOrder, out otherSide, out otherName);

                    if (area.GetLevelSet() == other.GetLevelSet() && order == otherOrder && name == otherName && side != otherSide &&
                        !other.HasMode(side))
                    {
                        if (other.Mode[(int)side] == null)
                        {
                            other.Mode[(int)side] = new ModeProperties {
                                Inventory  = PlayerInventory.Default,
                                AudioState = new AudioState(SFX.music_city, SFX.env_amb_00_main)
                            }
                        }
                        ;
                        other.Mode[(int)side].Path = path;
                        Areas.RemoveAt(i);
                        i--;
                        break;
                    }
                }
            }

            for (int i = 0; i < Areas.Count; i++)
            {
                AreaData area = Areas[i];
                area.ID = i;

                // Clean up non-existing modes.
                int modei = 0;
                for (; modei < area.Mode.Length; modei++)
                {
                    ModeProperties mode = area.Mode[modei];
                    if (mode == null || string.IsNullOrEmpty(mode.Path))
                    {
                        break;
                    }
                }
                Array.Resize(ref area.Mode, modei);

                Logger.Log("AreaData", $"{i}: {area.GetSID()} - {area.Mode.Length} sides");

                // Update old MapData areas and load any new areas.

                // Add the A side MapData or update its area key.
                if (area.Mode[0].MapData != null)
                {
                    area.Mode[0].MapData.Area = area.ToKey();
                }
                else
                {
                    area.Mode[0].MapData = new MapData(area.ToKey());
                }

                if (area.IsInterludeUnsafe())
                {
                    continue;
                }

                // A and (some) B sides have PoemIDs. Can be overridden via empty PoemID.
                if (area.Mode[0].PoemID == null)
                {
                    area.Mode[0].PoemID = area.GetSID().DialogKeyify() + "_A";
                }
                if (area.Mode.Length > 1 &&
                    area.Mode[1] != null &&
                    area.Mode[1].PoemID == null)
                {
                    area.Mode[1].PoemID = area.GetSID().DialogKeyify() + "_B";
                }

                // Update all other existing mode's area keys.
                for (int mode = 1; mode < area.Mode.Length; mode++)
                {
                    if (area.Mode[mode] == null)
                    {
                        continue;
                    }
                    if (area.Mode[mode].MapData != null)
                    {
                        area.Mode[mode].MapData.Area = area.ToKey((AreaMode)mode);
                    }
                    else
                    {
                        area.Mode[mode].MapData = new MapData(area.ToKey((AreaMode)mode));
                    }
                }
            }

            // Load custom mountains
            // This needs to be done after areas are loaded because it depends on the MapMeta
            MTNExt.LoadMod();
            MTNExt.LoadModData();
        }
コード例 #2
0
        public static new void Load()
        {
            orig_Load();

            foreach (AreaData area in Areas)
            {
                area.SetSID("Celeste/" + area.Mode[0].Path);
            }

            // Separate array as we sort it afterwards.
            List <AreaData> modAreas = new List <AreaData>();

            foreach (ModAsset asset in Everest.Content.ListMaps)
            {
                string  path = asset.PathMapped.Substring(5);
                MapMeta meta = asset.GetMeta <MapMeta>();

                AreaData area = new AreaData();

                // Default values.

                area.SetSID(path);

                area.Name = path;
                area.Icon = "areas/" + path.ToLowerInvariant();
                if (!GFX.Gui.Has(area.Icon))
                {
                    area.Icon = "areas/null";
                }

                area.TitleBaseColor   = Calc.HexToColor("6c7c81");
                area.TitleAccentColor = Calc.HexToColor("2f344b");
                area.TitleTextColor   = Color.White;

                area.IntroType = Player.IntroTypes.WakeUp;

                area.Dreaming   = false;
                area.ColorGrade = null;

                area.Mode = new ModeProperties[] {
                    new ModeProperties {
                        Path       = asset.PathMapped.Substring(5),
                        Inventory  = PlayerInventory.Default,
                        AudioState = new AudioState(Sfxs.music_city, Sfxs.env_amb_00_main)
                    }
                };

                area.Wipe = (Scene scene, bool wipeIn, Action onComplete)
                            => new AngledWipe(scene, wipeIn, onComplete);

                area.DarknessAlpha = 0.05f;
                area.BloomBase     = 0f;
                area.BloomStrength = 1f;

                area.Jumpthru = "wood";

                area.CassseteNoteColor = Calc.HexToColor("33a9ee");
                area.CassetteSong      = Sfxs.cas_01_forsaken_city;

                // Custom values.
                if (meta != null)
                {
                    if (!string.IsNullOrEmpty(meta.Name))
                    {
                        area.Name = meta.Name;
                    }

                    if (!string.IsNullOrEmpty(meta.SID))
                    {
                        area.SetSID(meta.SID);
                    }

                    if (!string.IsNullOrEmpty(meta.Icon) && GFX.Gui.Has(meta.Icon))
                    {
                        area.Icon = meta.Icon;
                    }

                    area.Interlude = meta.Interlude;
                    if (!string.IsNullOrEmpty(meta.CompleteScreenName))
                    {
                        area.CompleteScreenName = meta.CompleteScreenName;
                    }

                    area.CassetteCheckpointIndex = meta.CassetteCheckpointIndex;

                    if (!string.IsNullOrEmpty(meta.TitleBaseColor))
                    {
                        area.TitleBaseColor = Calc.HexToColor(meta.TitleBaseColor);
                    }
                    if (!string.IsNullOrEmpty(meta.TitleAccentColor))
                    {
                        area.TitleAccentColor = Calc.HexToColor(meta.TitleAccentColor);
                    }
                    if (!string.IsNullOrEmpty(meta.TitleTextColor))
                    {
                        area.TitleTextColor = Calc.HexToColor(meta.TitleTextColor);
                    }

                    area.IntroType = meta.IntroType;

                    area.Dreaming = meta.Dreaming;
                    if (!string.IsNullOrEmpty(meta.ColorGrade))
                    {
                        area.ColorGrade = meta.ColorGrade;
                    }

                    area.Mode = MapMeta.Convert(meta.Modes) ?? area.Mode;

                    if (!string.IsNullOrEmpty(meta.Wipe))
                    {
                        Type            type = Assembly.GetEntryAssembly().GetType(meta.Wipe);
                        ConstructorInfo ctor = type?.GetConstructor(new Type[] { typeof(Scene), typeof(bool), typeof(Action) });
                        if (type != null && ctor != null)
                        {
                            area.Wipe = (scene, wipeIn, onComplete) => ctor.Invoke(new object[] { scene, wipeIn, onComplete });
                        }
                    }

                    area.DarknessAlpha = meta.DarknessAlpha;
                    area.BloomBase     = meta.BloomBase;
                    area.BloomStrength = meta.BloomStrength;

                    if (!string.IsNullOrEmpty(meta.Jumpthru))
                    {
                        area.Jumpthru = meta.Jumpthru;
                    }

                    if (!string.IsNullOrEmpty(meta.CassetteNoteColor))
                    {
                        area.CassseteNoteColor = Calc.HexToColor(meta.CassetteNoteColor);
                    }
                    if (!string.IsNullOrEmpty(meta.CassetteSong))
                    {
                        area.CassetteSong = meta.CassetteSong;
                    }

                    area.MountainIdle   = meta.Mountain?.Idle?.Convert() ?? area.MountainIdle;
                    area.MountainSelect = meta.Mountain?.Select?.Convert() ?? area.MountainSelect;
                    area.MountainZoom   = meta.Mountain?.Zoom?.Convert() ?? area.MountainZoom;
                    area.MountainCursor = meta.Mountain?.Cursor?.ToVector3() ?? area.MountainCursor;
                    area.MountainState  = meta.Mountain?.State ?? area.MountainState;

                    area.SetCompleteScreenMeta(meta.CompleteScreen);
                }

                // Some of the game's code checks for [1] / [2] explicitly.
                // Let's just provide null modes to fill any gaps.
                if (area.Mode.Length < 3)
                {
                    ModeProperties[] larger = new ModeProperties[3];
                    for (int i = 0; i < area.Mode.Length; i++)
                    {
                        larger[i] = area.Mode[i];
                    }
                    area.Mode = larger;
                }

                // Celeste levelset always appears first.
                if (area.GetLevelSet() == "Celeste")
                {
                    Areas.Add(area);
                }
                else
                {
                    modAreas.Add(area);
                }
            }


            // Sort and merge modAreas into Areas. Makes for easier levelset handling.
            Areas.Sort(AreaComparison);
            modAreas.Sort(AreaComparison);
            Areas.AddRange(modAreas);

            // Find duplicates and remove the earlier copy.
            for (int i = 0; i < Areas.Count; i++)
            {
                AreaData area       = Areas[i];
                int      otherIndex = Areas.FindIndex(other => other.GetSID() == area.GetSID());
                if (otherIndex < i)
                {
                    Areas[otherIndex] = area;
                    Areas.RemoveAt(i);
                    i--;
                }
            }

            // Remove AreaDatas which are now a mode of another AreaData.
            for (int i = 0; i < Areas.Count; i++)
            {
                AreaData area       = Areas[i];
                int      otherIndex = Areas.FindIndex(other => other.Mode.Any(otherMode => otherMode?.Path == area.Mode[0].Path));
                if (otherIndex != -1 && otherIndex != i)
                {
                    Areas.RemoveAt(i);
                    i--;
                }
            }

            // Update old MapData areas and load any new areas.
            for (int i = 0; i < Areas.Count; i++)
            {
                AreaData area = Areas[i];
                area.ID = i;
                if (area.Mode[0].MapData != null)
                {
                    area.Mode[0].MapData.Area = area.ToKey();
                }
                else
                {
                    area.Mode[0].MapData = new MapData(area.ToKey());
                }
                if (area.Interlude)
                {
                    continue;
                }
                for (int mode = 1; mode < area.Mode.Length; mode++)
                {
                    if (area.Mode[mode] == null)
                    {
                        continue;
                    }
                    if (area.Mode[mode].MapData != null)
                    {
                        area.Mode[mode].MapData.Area = area.ToKey((AreaMode)mode);
                    }
                    else
                    {
                        area.Mode[mode].MapData = new MapData(area.ToKey((AreaMode)mode));
                    }
                }
            }
        }