Exemplo n.º 1
0
        private IEnumerator CollectRoutine(Player player)
        {
            Level level = Scene as Level;

            bool heartIsEnd = false;
            MapMetaModeProperties mapMetaModeProperties = (level != null) ? level.Session.MapData.GetMeta() : null;

            if (mapMetaModeProperties != null && mapMetaModeProperties.HeartIsEnd != null)
            {
                heartIsEnd = mapMetaModeProperties.HeartIsEnd.Value;
            }

            heartIsEnd &= !IsFake;

            if (heartIsEnd)
            {
                List <IStrawberry>        strawbs    = new List <IStrawberry>();
                ReadOnlyCollection <Type> regBerries = StrawberryRegistry.GetBerryTypes();
                foreach (Follower follower in player.Leader.Followers)
                {
                    if (regBerries.Contains(follower.Entity.GetType()) && follower.Entity is IStrawberry)
                    {
                        strawbs.Add(follower.Entity as IStrawberry);
                    }
                }
                foreach (IStrawberry strawb in strawbs)
                {
                    strawb.OnCollect();
                }
            }

            return(orig_CollectRoutine(player));
        }
Exemplo n.º 2
0
        private void YellowBoostBegin()
        {
            Player player = StateGetPlayer();

            player.CurrentBooster = null;
            Level level = player.SceneAs <Level>();
            bool? flag;

            if (level == null)
            {
                flag = null;
            }
            else
            {
                MapMetaModeProperties meta = level.Session.MapData.GetMeta();
                flag = meta?.TheoInBubble;
            }
            bool?flag2 = flag;

            player.RefillDash();
            player.RefillStamina();
            if (flag2.GetValueOrDefault())
            {
                return;
            }
            player.Drop();
        }
Exemplo n.º 3
0
        private bool IsCompleteArea(bool value)
        {
            MapMetaModeProperties mapMetaModeProperties = (base.Scene as Level)?.Session.MapData.GetMeta();

            if (mapMetaModeProperties != null && mapMetaModeProperties.HeartIsEnd.HasValue)
            {
                return(mapMetaModeProperties.HeartIsEnd.Value);
            }
            return(value);
        }
Exemplo n.º 4
0
        private bool IsCompleteArea(bool value)
        {
            MapMetaModeProperties meta = (Scene as Level)?.Session.MapData.GetMeta();

            if (meta?.HeartIsEnd != null)
            {
                return(meta.HeartIsEnd.Value && !IsFake);
            }

            return(value);
        }
Exemplo n.º 5
0
        public new LevelData StartLevel()
        {
            MapMetaModeProperties meta = Meta;

            if (meta != null)
            {
                if (!string.IsNullOrEmpty(meta.StartLevel))
                {
                    LevelData level = Levels.FirstOrDefault(_ => _.Name == meta.StartLevel);
                    if (level != null)
                    {
                        return(level);
                    }
                }
            }

            return(orig_StartLevel() ?? Levels[0]);
        }
        public virtual void HandleBoostBegin(Player player)
        {
            Level level         = player.SceneAs <Level>();
            bool  doNotDropTheo = false;

            if (level != null)
            {
                MapMetaModeProperties meta = level.Session.MapData.GetMeta();
                doNotDropTheo = (meta != null) && meta.TheoInBubble.GetValueOrDefault();
            }
            player.RefillDash();
            player.RefillStamina();
            if (doNotDropTheo)
            {
                return;
            }
            player.Drop();
        }
Exemplo n.º 7
0
        private AreaMode _PatchHeartGemBehavior(AreaMode levelMode)
        {
            if (Session.Area.GetLevelSet() == "Celeste")
            {
                // do not mess with vanilla.
                return(levelMode);
            }

            MapMetaModeProperties properties = Session.MapData.GetMeta();

            if (properties != null && (properties.HeartIsEnd ?? false))
            {
                // heart ends the level: this is like B-Sides.
                // the heart will appear even if it was collected, to avoid a softlock if we save & quit after collecting it.
                return(AreaMode.BSide);
            }
            else
            {
                // heart does not end the level: this is like A-Sides.
                // the heart will disappear after it is collected.
                return(AreaMode.Normal);
            }
        }
Exemplo n.º 8
0
        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();
        }