Exemple #1
0
 public void ctor(BinaryPacker.Element data)
 {
     orig_ctor(data);
     if (!Everest.Flags.IsDisabled)
     {
         MakeIdUnique();
     }
 }
Exemple #2
0
 private static BinaryPacker.Element _Process(BinaryPacker.Element root, MapData self)
 {
     if (self.Area.GetLevelSet() == "Celeste")
     {
         return(root);
     }
     return(((patch_MapData)self).Process(root));
 }
Exemple #3
0
 internal static bool AttrIfBool(this BinaryPacker.Element el, string name, Action <bool> value)
 {
     if (el.HasAttr(name))
     {
         value(el.AttrBool(name));
         return(true);
     }
     return(false);
 }
Exemple #4
0
 public static bool AttrRef(this BinaryPacker.Element el, string name, ref int value)
 {
     if (el.HasAttr(name))
     {
         value = int.Parse(el.Attr(name));
         return(true);
     }
     return(false);
 }
        public virtual void Run(string stepName, BinaryPacker.Element el)
        {
            Dictionary <string, Action <BinaryPacker.Element> > steps = Steps;

            if (steps != null && steps.TryGetValue(stepName, out Action <BinaryPacker.Element> step) && step != null)
            {
                step(el);
            }
        }
Exemple #6
0
 public static bool AttrIfFloat(this BinaryPacker.Element el, string name, Action <float> value)
 {
     if (el.HasAttr(name))
     {
         value(el.AttrFloat(name));
         return(true);
     }
     return(false);
 }
Exemple #7
0
 public static bool AttrIfInt(this BinaryPacker.Element el, string name, Action <int> value)
 {
     if (el.HasAttr(name))
     {
         value(int.Parse(el.Attr(name)));
         return(true);
     }
     return(false);
 }
Exemple #8
0
 public void Parse(BinaryPacker.Element meta)
 {
     meta.AttrIfFloat("TempoMult", v => TempoMult     = v);
     meta.AttrIfInt("LeadBeats", v => LeadBeats       = v);
     meta.AttrIfInt("BeatsPerTick", v => BeatsPerTick = v);
     meta.AttrIfInt("TicksPerSwap", v => TicksPerSwap = v);
     meta.AttrIfInt("Blocks", v => Blocks             = v);
     meta.AttrIfInt("BeatsMax", v => BeatsMax         = v);
 }
Exemple #9
0
 public static BinaryPacker.Element SetAttr(this BinaryPacker.Element el, string name, object value)
 {
     if (el.Attributes == null)
     {
         el.Attributes = new Dictionary <string, object>();
     }
     el.Attributes[name] = value;
     return(el);
 }
Exemple #10
0
 internal static bool AttrRef(this BinaryPacker.Element el, string name, ref float value)
 {
     if (el.HasAttr(name))
     {
         value = el.AttrFloat(name);
         return(true);
     }
     return(false);
 }
        public static bool TrackableContains(BinaryPacker.Element target)
        {
            if (target.AttrBool("moon", false))
            {
                return(false);
            }

            return(TrackableContains(target.Name));
        }
Exemple #12
0
        public void Parse(BinaryPacker.Element meta)
        {
            meta.AttrIf("Name", v => Name = v);
            meta.AttrIf("SID", v => SID   = v);
            meta.AttrIf("Icon", v => Icon = v);

            meta.AttrIfBool("Interlude", v => Interlude = v);
            meta.AttrIf("CompleteScreenName", v => CompleteScreenName = v);

            meta.AttrIfInt("CassetteCheckpointIndex", v => CassetteCheckpointIndex = v);

            meta.AttrIf("TitleBaseColor", v => TitleBaseColor     = v);
            meta.AttrIf("TitleAccentColor", v => TitleAccentColor = v);
            meta.AttrIf("TitleTextColor", v => TitleTextColor     = v);

            meta.AttrIf("IntroType", v => IntroType = (Player.IntroTypes)Enum.Parse(typeof(Player.IntroTypes), v, true));

            meta.AttrIfBool("Dreaming", v => Dreaming = v);

            meta.AttrIf("ColorGrade", v => ColorGrade = v);

            meta.AttrIf("Wipe", v => Wipe = v);

            meta.AttrIfFloat("DarknessAlpha", (float v) => DarknessAlpha = v);
            meta.AttrIfFloat("BloomBase", (float v) => BloomBase         = v);
            meta.AttrIfFloat("BloomStrength", (float v) => BloomStrength = v);

            meta.AttrIf("Jumpthru", v => Jumpthru = v);

            meta.AttrIf("CoreMode", v => CoreMode = (Session.CoreModes)Enum.Parse(typeof(Session.CoreModes), v, true));

            meta.AttrIf("CassetteNoteColor", v => CassetteNoteColor = v);
            meta.AttrIf("CassetteSong", v => CassetteSong           = v);

            BinaryPacker.Element child;

            child = meta.Children.FirstOrDefault(el => el.Name == "cassettemodifier");
            if (child != null)
            {
                CassetteModifier = new MapMetaCassetteModifier(child);
            }

            Modes = new MapMetaModeProperties[3];
            child = meta.Children.FirstOrDefault(el => el.Name == "modes");
            if (child != null)
            {
                for (int i = 0; i < child.Children.Count; i++)
                {
                    Modes[i] = new MapMetaModeProperties(child.Children[i]);
                }
                for (int i = child.Children.Count; i < Modes.Length; i++)
                {
                    Modes[i] = null;
                }
            }
        }
        public static BlackholeBG CreateBlackholeWithCustomColors(BinaryPacker.Element effectData)
        {
            if (!effectData.Attr("colorsMild").Contains("|") &&
                !effectData.Attr("colorsWild").Contains("|") &&
                !effectData.Attr("bgColorInner").Contains("|") &&
                !effectData.Attr("bgColorOuterMild").Contains("|") &&
                !effectData.Attr("bgColorOuterWild").Contains("|"))
            {
                // there is no gradient on any color: we can just instanciate a vanilla blackhole and mess with its properties.

                // set up colorsMild for the hook above. we can't use DynData to pass this over, since the object does not exist yet!
                colorsMild = parseColors(effectData.Attr("colorsMild", "6e3199,851f91,3026b0"));
                for (int i = 0; i < colorsMild.Length; i++)
                {
                    colorsMild[i] *= 0.8f;
                }

                // build the blackhole: the hook will take care of setting colorsMild.
                BlackholeBG blackhole = new BlackholeBG();

                // ... now we've got to set everything else.
                DynData <BlackholeBG> blackholeData = new DynData <BlackholeBG>(blackhole);
                blackholeData["colorsWild"]       = parseColors(effectData.Attr("colorsWild", "ca4ca7,b14cca,ca4ca7"));
                blackholeData["bgColorInner"]     = Calc.HexToColor(effectData.Attr("bgColorInner", "000000"));
                blackholeData["bgColorOuterMild"] = Calc.HexToColor(effectData.Attr("bgColorOuterMild", "512a8b"));
                blackholeData["bgColorOuterWild"] = Calc.HexToColor(effectData.Attr("bgColorOuterWild", "bd2192"));
                blackhole.Alpha = effectData.AttrFloat("alpha", 1f);

                return(blackhole);
            }
            else
            {
                // there are gradients: we need a custom blackhole!

                // set up colorsMild for the hook above. we can't use DynData to pass this over, since the object does not exist yet!
                colorsMild = new ColorCycle(effectData.Attr("colorsMild", "6e3199,851f91,3026b0"), 0.8f).GetColors();

                // build the blackhole: the hook will take care of setting colorsMild.
                BlackholeCustomColors blackhole = new BlackholeCustomColors(
                    effectData.Attr("colorsMild", "6e3199,851f91,3026b0"),
                    effectData.Attr("colorsWild", "ca4ca7,b14cca,ca4ca7"),
                    effectData.Attr("bgColorInner", "000000"),
                    effectData.Attr("bgColorOuterMild", "512a8b"),
                    effectData.Attr("bgColorOuterWild", "bd2192"));

                // ... now we've got to set the initial values of everything else.
                blackhole.blackholeData["colorsWild"]       = blackhole.cycleColorsWild.GetColors();
                blackhole.blackholeData["bgColorInner"]     = blackhole.cycleBgColorInner.GetColors()[0];
                blackhole.blackholeData["bgColorOuterMild"] = blackhole.cycleBgColorOuterMild.GetColors()[0];
                blackhole.blackholeData["bgColorOuterWild"] = blackhole.cycleBgColorOuterWild.GetColors()[0];
                blackhole.Alpha = effectData.AttrFloat("alpha", 1f);

                return(blackhole);
            }
        }
Exemple #14
0
 public void Parse(BinaryPacker.Element meta)
 {
     meta.AttrIfFloat("TempoMult", v => TempoMult           = v);
     meta.AttrIfInt("LeadBeats", v => LeadBeats             = v);
     meta.AttrIfInt("BeatsPerTick", v => BeatsPerTick       = v);
     meta.AttrIfInt("TicksPerSwap", v => TicksPerSwap       = v);
     meta.AttrIfInt("Blocks", v => Blocks                   = v);
     meta.AttrIfInt("BeatsMax", v => BeatsMax               = v);
     meta.AttrIfInt("BeatIndexOffset", v => BeatIndexOffset = v);
     meta.AttrIfBool("OldBehavior", v => OldBehavior        = v);
 }
Exemple #15
0
 public static int AttrInt(this BinaryPacker.Element el, string name, int defaultValue = 0)
 {
     if (el.Attributes == null || !el.Attributes.TryGetValue(name, out object obj))
     {
         return(defaultValue);
     }
     if (obj is int)
     {
         return((int)obj);
     }
     return(int.Parse(obj.ToString(), CultureInfo.InvariantCulture));
 }
        public override void Run(string stepName, BinaryPacker.Element el)
        {
            if (StrawberryRegistry.TrackableContains(el))
            {
                stepName = "entity:strawberry";
            }

            if (StrawberryRegistry.GetRegisteredBerries().Any(berry => berry.entityName == el.Name))
            {
                TotalStrawberriesIncludingUntracked++;
            }

            base.Run(stepName, el);
        }
Exemple #17
0
        public void Process(BinaryPacker.Element root)
        {
            Root = root;

            foreach (EverestMapDataProcessor p in Processors)
            {
                p.Reset();
            }

            Run("root", root);

            foreach (EverestMapDataProcessor p in Processors)
            {
                p.End();
            }
        }
Exemple #18
0
        private BinaryPacker.Element Process(BinaryPacker.Element root)
        {
            if (root.Children == null)
            {
                return(root);
            }

            // make sure parse meta first, because checkpoint entity needs to read meta
            if (root.Children.Find(element => element.Name == "meta") is BinaryPacker.Element meta)
            {
                ProcessMeta(meta);
            }

            new MapDataFixup(this).Process(root);

            return(root);
        }
Exemple #19
0
        private BinaryPacker.Element Process(BinaryPacker.Element root)
        {
            foreach (BinaryPacker.Element el in root.Children)
            {
                switch (el.Name)
                {
                case "levels":
                    ProcessLevels(el);
                    continue;

                case "meta":
                    ProcessMeta(el);
                    continue;
                }
            }

            return(root);
        }
Exemple #20
0
        private BinaryPacker.Element Process(BinaryPacker.Element root)
        {
            if (root.Children == null)
            {
                return(root);
            }

            // make sure parse meta first, because checkpoint entity needs to read meta
            if (root.Children.Find(element => element.Name == "meta") is BinaryPacker.Element meta)
            {
                ProcessMeta(meta);
            }

            foreach (BinaryPacker.Element el in root.Children)
            {
                switch (el.Name)
                {
                case "levels":
                    ProcessLevels(el);
                    continue;

                // Celeste 1.2.5.0 optimizes BinaryPacker, which causes some issues.
                // Let's "unoptimize" Style and its Backgrounds and Foregrounds.
                case "Style":
                    if (el.Children == null)
                    {
                        el.Children = new List <BinaryPacker.Element>();
                    }
                    foreach (BinaryPacker.Element style in el.Children)
                    {
                        if ((
                                style.Name == "Backgrounds" ||
                                style.Name == "Foregrounds"
                                ) && style.Children == null)
                        {
                            style.Children = new List <BinaryPacker.Element>();
                        }
                    }
                    continue;
                }
            }

            return(root);
        }
Exemple #21
0
        private void ProcessMeta(BinaryPacker.Element meta)
        {
            AreaData area = AreaData.Get(Area);
            AreaMode mode = Area.Mode;

            if (mode == AreaMode.Normal)
            {
                new MapMeta(meta).ApplyTo(area);
                Area = area.ToKey();
            }

            meta = meta.Children?.FirstOrDefault(el => el.Name == "mode");
            if (meta == null)
            {
                return;
            }

            new MapMetaModeProperties(meta).ApplyTo(area, mode);
        }
Exemple #22
0
        private BinaryPacker.Element Process(BinaryPacker.Element root)
        {
            if (root.Children == null)
            {
                return(root);
            }

            foreach (BinaryPacker.Element el in root.Children)
            {
                switch (el.Name)
                {
                case "levels":
                    ProcessLevels(el);
                    continue;

                case "meta":
                    ProcessMeta(el);
                    continue;

                // Celeste 1.2.5.0 optimizes BinaryPacker, which causes some issues.
                // Let's "unoptimize" Style and its Backgrounds and Foregrounds.
                case "Style":
                    if (el.Children == null)
                    {
                        el.Children = new List <BinaryPacker.Element>();
                    }
                    foreach (BinaryPacker.Element style in el.Children)
                    {
                        if ((
                                style.Name == "Backgrounds" ||
                                style.Name == "Foregrounds"
                                ) && style.Children == null)
                        {
                            style.Children = new List <BinaryPacker.Element>();
                        }
                    }
                    continue;
                }
            }

            return(root);
        }
Exemple #23
0
        public static Backdrop LoadCustomBackdrop(BinaryPacker.Element child, BinaryPacker.Element above, MapData map)
        {
            Backdrop backdropFromMod = Everest.Events.Level.LoadBackdrop(map, child, above);

            if (backdropFromMod != null)
            {
                return(backdropFromMod);
            }

            if (child.Name.Equals("rain", StringComparison.OrdinalIgnoreCase))
            {
                patch_RainFG rain = new patch_RainFG();
                if (child.HasAttr("color"))
                {
                    rain.Color = Calc.HexToColor(child.Attr("color"));
                }
                return(rain);
            }

            return(null);
        }
Exemple #24
0
        private void ProcessMeta(BinaryPacker.Element meta)
        {
            AreaData area = AreaData.Get(Area);
            AreaMode mode = Area.Mode;

            if (mode == AreaMode.Normal)
            {
                new MapMeta(meta).ApplyTo(area);
                Area = area.ToKey();

                // Backup A-Side's Metadata. Only back up useful data.
                area.SetASideAreaDataBackup(new AreaData {
                    IntroType     = area.IntroType,
                    ColorGrade    = area.ColorGrade,
                    DarknessAlpha = area.DarknessAlpha,
                    BloomBase     = area.BloomBase,
                    BloomStrength = area.BloomStrength,
                    CoreMode      = area.CoreMode,
                    Dreaming      = area.Dreaming
                });
            }

            BinaryPacker.Element modeMeta = meta.Children?.FirstOrDefault(el => el.Name == "mode");
            if (modeMeta == null)
            {
                return;
            }

            new MapMetaModeProperties(modeMeta).ApplyTo(area, mode);

            // Metadata for B-Side and C-Side are parsed and stored.
            if (mode != AreaMode.Normal)
            {
                MapMeta mapMeta = new MapMeta(meta)
                {
                    Modes = area.GetMeta().Modes
                };
                area.Mode[(int)mode].SetMapMeta(mapMeta);
            }
        }
        public static BlackholeBG CreateBlackholeWithCustomColors(BinaryPacker.Element effectData)
        {
            // set up colorsMild for the hook above. we can't use DynData to pass this over, since the object does not exist yet!
            colorsMild = parseColors(effectData.Attr("colorsMild", "6e3199,851f91,3026b0"));
            for (int i = 0; i < colorsMild.Length; i++)
            {
                colorsMild[i] *= 0.8f;
            }

            // build the blackhole: the hook will take care of setting colorsMild.
            BlackholeBG blackhole = new BlackholeBG();

            // ... now we've got to set everything else.
            DynData <BlackholeBG> blackholeData = new DynData <BlackholeBG>(blackhole);

            blackholeData["colorsWild"]       = parseColors(effectData.Attr("colorsWild", "ca4ca7,b14cca,ca4ca7"));
            blackholeData["bgColorInner"]     = Calc.HexToColor(effectData.Attr("bgColorInner", "000000"));
            blackholeData["bgColorOuterMild"] = Calc.HexToColor(effectData.Attr("bgColorOuterMild", "512a8b"));
            blackholeData["bgColorOuterWild"] = Calc.HexToColor(effectData.Attr("bgColorOuterWild", "bd2192"));
            blackhole.Alpha = effectData.AttrFloat("alpha", 1f);

            return(blackhole);
        }
Exemple #26
0
        private Backdrop onLoadBackdrop(MapData map, BinaryPacker.Element child, BinaryPacker.Element above)
        {
            if (child.Name.Equals("SpringCollab2020/HeatWaveNoColorGrade", StringComparison.OrdinalIgnoreCase))
            {
                return(new HeatWaveNoColorGrade());
            }
            if (child.Name.Equals("SpringCollab2020/CustomSnow", StringComparison.OrdinalIgnoreCase))
            {
                string[] colorsAsStrings = child.Attr("colors").Split(',');
                Color[]  colors          = new Color[colorsAsStrings.Length];
                for (int i = 0; i < colors.Length; i++)
                {
                    colors[i] = Calc.HexToColor(colorsAsStrings[i]);
                }

                return(new CustomSnow(colors, child.AttrBool("foreground")));
            }
            if (child.Name.Equals("SpringCollab2020/BlackholeCustomColors", StringComparison.OrdinalIgnoreCase))
            {
                return(BlackholeCustomColors.CreateBlackholeWithCustomColors(child));
            }
            return(null);
        }
Exemple #27
0
        private void ProcessLevels(BinaryPacker.Element levels)
        {
            AreaData       area = AreaData.Get(Area);
            ModeProperties mode = area.Mode[(int)Area.Mode];

            // Mod levels are... different.

            // levels.Children.Sort((a, b) => a.Attr("name").Replace("lvl_", "").CompareTo(b.Attr("name").Replace("lvl_", "")));

            int checkpoint = 0;
            List <CheckpointData> checkpointsAuto = null;

            if (mode.Checkpoints == null)
            {
                checkpointsAuto = new List <CheckpointData>();
            }

            int strawberry             = 0;
            int strawberryInCheckpoint = 0;

            if (levels.Children != null)
            {
                foreach (BinaryPacker.Element level in levels.Children)
                {
                    string[] levelTags = level.Attr("name").Split(':');
                    string   levelName = levelTags[0];
                    if (levelName.StartsWith("lvl_"))
                    {
                        levelName = levelName.Substring(4);
                    }
                    level.SetAttr("name", "lvl_" + levelName); // lvl_ was optional before Celeste 1.2.5.0 made it mandatory.

                    BinaryPacker.Element entities = level.Children.FirstOrDefault(el => el.Name == "entities");
                    BinaryPacker.Element triggers = level.Children.FirstOrDefault(el => el.Name == "triggers");

                    // Celeste 1.2.5.0 optimizes BinaryPacker, which causes some issues.
                    // Let's "unoptimize" entities and triggers.
                    if (entities == null)
                    {
                        level.Children.Add(entities = new BinaryPacker.Element {
                            Name = "entities"
                        });
                    }
                    if (entities.Children == null)
                    {
                        entities.Children = new List <BinaryPacker.Element>();
                    }

                    if (triggers == null)
                    {
                        level.Children.Add(triggers = new BinaryPacker.Element {
                            Name = "triggers"
                        });
                    }
                    if (triggers.Children == null)
                    {
                        triggers.Children = new List <BinaryPacker.Element>();
                    }

                    if (levelTags.Contains("checkpoint") || levelTags.Contains("cp"))
                    {
                        entities.Children.Add(new BinaryPacker.Element {
                            Name       = "checkpoint",
                            Attributes = new Dictionary <string, object>()
                            {
                                { "x", "0" },
                                { "y", "0" }
                            }
                        });
                    }

                    if (level.AttrBool("space"))
                    {
                        if (level.AttrBool("spaceSkipWrap") || levelTags.Contains("nospacewrap") || levelTags.Contains("nsw"))
                        {
                            entities.Children.Add(new BinaryPacker.Element {
                                Name = "everest/spaceControllerBlocker"
                            });
                        }
                        if (level.AttrBool("spaceSkipGravity") || levelTags.Contains("nospacegravity") || levelTags.Contains("nsg"))
                        {
                            entities.Children.Add(new BinaryPacker.Element {
                                Name = "everest/spaceController"
                            });
                            level.SetAttr("space", false);
                        }

                        if (!levelTags.Contains("nospacefix") && !levelTags.Contains("nsf") &&
                            !triggers.Children.Any(el => el.Name == "cameraTargetTrigger") &&
                            !entities.Children.Any(el => el.Name == "everest/spaceControllerBlocker"))
                        {
                            // Camera centers tile-perfectly on uneven heights.
                            int heightForCenter = level.AttrInt("height");
                            heightForCenter /= 8;
                            if (heightForCenter % 2 == 0)
                            {
                                heightForCenter--;
                            }
                            heightForCenter *= 8;

                            triggers.Children.Add(new BinaryPacker.Element {
                                Name       = "cameraTargetTrigger",
                                Attributes = new Dictionary <string, object>()
                                {
                                    { "x", 0f },
                                    { "y", 0f },
                                    { "width", level.AttrInt("width") },
                                    { "height", level.AttrInt("height") },
                                    { "yOnly", true },
                                    { "lerpStrength", 1f }
                                },
                                Children = new List <BinaryPacker.Element>()
                                {
                                    new BinaryPacker.Element {
                                        Attributes = new Dictionary <string, object>()
                                        {
                                            { "x", 160f },
                                            { "y", heightForCenter / 2f }
                                        }
                                    }
                                }
                            });
                        }
                    }

                    foreach (BinaryPacker.Element levelChild in level.Children)
                    {
                        switch (levelChild.Name)
                        {
                        case "entities":
                            foreach (BinaryPacker.Element entity in levelChild.Children)
                            {
                                switch (entity.Name)
                                {
                                case "checkpoint":
                                    if (checkpointsAuto != null)
                                    {
                                        CheckpointData c = new CheckpointData(
                                            levelName,
                                            (area.GetSID() + "_" + levelName).DialogKeyify(),
                                            MapMeta.GetInventory(entity.Attr("inventory")),
                                            entity.Attr("dreaming") == "" ? area.Dreaming : entity.AttrBool("dreaming"),
                                            null
                                            );
                                        int id = entity.AttrInt("checkpointID", -1);
                                        if (id == -1)
                                        {
                                            checkpointsAuto.Add(c);
                                        }
                                        else
                                        {
                                            while (checkpointsAuto.Count <= id)
                                            {
                                                checkpointsAuto.Add(null);
                                            }
                                            checkpointsAuto[id] = c;
                                        }
                                    }
                                    checkpoint++;
                                    strawberryInCheckpoint = 0;
                                    break;

                                case "cassette":
                                    if (area.CassetteCheckpointIndex == 0)
                                    {
                                        area.CassetteCheckpointIndex = checkpoint;
                                    }
                                    break;

                                case "strawberry":
                                    if (entity.AttrInt("checkpointID", -1) == -1)
                                    {
                                        entity.SetAttr("checkpointID", checkpoint);
                                    }
                                    if (entity.AttrInt("order", -1) == -1)
                                    {
                                        entity.SetAttr("order", strawberryInCheckpoint);
                                    }
                                    strawberry++;
                                    strawberryInCheckpoint++;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }

            if (mode.Checkpoints == null)
            {
                mode.Checkpoints = checkpointsAuto.Where(c => c != null).ToArray();
            }
        }
Exemple #28
0
 public patch_LevelData(BinaryPacker.Element data) : base(data)
 {
     // no-op. MonoMod ignores this - we only need this to make the compiler shut up.
 }
Exemple #29
0
 internal static Backdrop LoadBackdrop(MapData map, BinaryPacker.Element child, BinaryPacker.Element above)
 => OnLoadBackdrop?.InvokeWhileNull <Backdrop>(map, child, above);
Exemple #30
0
 [PatchBackdropParser] // ... except for manually manipulating the method via MonoModRules
 private extern Backdrop ParseBackdrop(BinaryPacker.Element child, BinaryPacker.Element above);