Skip to content

Commit

Permalink
Revert "Make metadata loading consistent; closes #438 (#503)"
Browse files Browse the repository at this point in the history
This reverts commit e8b16ea.
Following reports of unforeseen impacts on maps such as Glyph and Etselec.
  • Loading branch information
maddie480 committed Jul 28, 2024
1 parent 5723cd6 commit dc0d4cb
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 169 deletions.
191 changes: 59 additions & 132 deletions Celeste.Mod.mm/Mod/Meta/MapMeta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,7 @@ public MapMeta(BinaryPacker.Element meta) {

public bool? OverrideASideMeta { get; set; }

private MapMetaModeProperties[] _modes = new MapMetaModeProperties[3];
public MapMetaModeProperties[] Modes {
get => _modes;
set {
_modes = value;
// Some of the game's code checks for [1] / [2] explicitly.
// Let's just provide null modes to fill any gaps.
Array.Resize(ref _modes, 3);
}
}
public MapMetaModeProperties Mode { get; set; } // This property will be null outside of loading
public MapMetaModeProperties[] Modes { get; set; }

public MapMetaMountain Mountain { get; set; }

Expand Down Expand Up @@ -131,7 +121,8 @@ public void Parse(BinaryPacker.Element meta) {
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 && child.Children != null) {
for (int i = 0; i < child.Children.Count; i++) {
Expand All @@ -141,72 +132,6 @@ public void Parse(BinaryPacker.Element meta) {
Modes[i] = null;
}
}
BinaryPacker.Element modeMeta = meta.Children?.FirstOrDefault(el => el.Name == "mode");
if (modeMeta != null) {
Mode = new MapMetaModeProperties(modeMeta);
}
}

public void AddTo(MapMeta other) {
if (!string.IsNullOrEmpty(Parent)) { other.Parent = Parent; }
if (!string.IsNullOrEmpty(Icon)) { other.Icon = Icon; }
if (Interlude != null) { other.Interlude = Interlude; }
if (CassetteCheckpointIndex != null) { other.CassetteCheckpointIndex = CassetteCheckpointIndex; }
if (!string.IsNullOrEmpty(TitleBaseColor)) { other.TitleBaseColor = TitleBaseColor; }
if (!string.IsNullOrEmpty(TitleAccentColor)) { other.TitleAccentColor = TitleAccentColor; }
if (!string.IsNullOrEmpty(TitleTextColor)) { other.TitleTextColor = TitleTextColor; }
if (IntroType != null) { other.IntroType = IntroType; }
if (Dreaming != null) { other.Dreaming = Dreaming; }
if (!string.IsNullOrEmpty(ColorGrade)) { other.ColorGrade = ColorGrade; }
if (!string.IsNullOrEmpty(Wipe)) { other.Wipe = Wipe; }
if (DarknessAlpha != null) { other.DarknessAlpha = DarknessAlpha; }
if (BloomBase != null) { other.BloomBase = BloomBase; }
if (BloomStrength != null) { other.BloomStrength = BloomStrength; }
if (!string.IsNullOrEmpty(Jumpthru)) { other.Jumpthru = Jumpthru; }
if (CoreMode != null) { other.CoreMode = CoreMode; }
if (!string.IsNullOrEmpty(CassetteNoteColor)) { other.CassetteNoteColor = CassetteNoteColor; }
if (!string.IsNullOrEmpty(CassetteSong)) { other.CassetteSong = CassetteSong; }
if (!string.IsNullOrEmpty(PostcardSoundID)) { other.PostcardSoundID = PostcardSoundID; }
if (!string.IsNullOrEmpty(ForegroundTiles)) { other.ForegroundTiles = ForegroundTiles; }
if (!string.IsNullOrEmpty(BackgroundTiles)) { other.BackgroundTiles = BackgroundTiles; }
if (!string.IsNullOrEmpty(AnimatedTiles)) { other.AnimatedTiles = AnimatedTiles; }
if (!string.IsNullOrEmpty(Sprites)) { other.Sprites = Sprites; }
if (!string.IsNullOrEmpty(Portraits)) { other.Portraits = Portraits; }
if (OverrideASideMeta != null) { other.OverrideASideMeta = OverrideASideMeta; }
if (Modes != null) {
if (other.Modes == null) {
other.Modes = Modes;
} else {
for (int i = 0; i < Modes.Length && i < other.Modes.Length; i++) {
if (other.Modes[i] == null) {
other.Modes[i] = Modes[i];
} else if (Modes[i] != null) {
Modes[i].AddTo(other.Modes[i]);
}
}
}
}
if (Mountain != null) { other.Mountain = Mountain; }
if (CompleteScreen != null) { other.CompleteScreen = CompleteScreen; }
if (LoadingVignetteScreen != null) { other.LoadingVignetteScreen = LoadingVignetteScreen; }
if (LoadingVignetteText != null) { other.LoadingVignetteText = LoadingVignetteText; }
if (CassetteModifier != null) { other.CassetteModifier = CassetteModifier; }
}

public static MapMeta Add(MapMeta self, MapMeta other) {
switch ((self, other)) {
case (null, null):
return new MapMeta();
case (null, _):
return other;
case (_, null):
return self;
default:
MapMeta result = new MapMeta();
other.AddTo(result);
self.AddTo(result);
return result;
}
}

public void ApplyTo(patch_AreaData area) {
Expand Down Expand Up @@ -267,7 +192,59 @@ public void ApplyTo(patch_AreaData area) {
area.MountainCursor = Mountain?.Cursor?.ToVector3() ?? area.MountainCursor;
area.MountainState = Mountain?.State ?? area.MountainState;

area.Meta = this;
patch_ModeProperties[] modes = area.Mode;
area.Mode = Convert(Modes) ?? modes;
if (modes != null)
for (int i = 0; i < area.Mode.Length && i < modes.Length; i++)
if (area.Mode[i] == null)
area.Mode[i] = modes[i];

MapMeta meta = area.Meta;
if (meta == null) {
area.Meta = this;
} else {
if (!string.IsNullOrEmpty(Parent))
meta.Parent = Parent;

if (!string.IsNullOrEmpty(PostcardSoundID))
meta.PostcardSoundID = PostcardSoundID;

if (!string.IsNullOrEmpty(ForegroundTiles))
meta.ForegroundTiles = ForegroundTiles;

if (!string.IsNullOrEmpty(BackgroundTiles))
meta.BackgroundTiles = BackgroundTiles;

if (!string.IsNullOrEmpty(AnimatedTiles))
meta.AnimatedTiles = AnimatedTiles;

if (!string.IsNullOrEmpty(Sprites))
meta.Sprites = Sprites;

if (!string.IsNullOrEmpty(Portraits))
meta.Portraits = Portraits;

if (OverrideASideMeta != null)
meta.OverrideASideMeta = OverrideASideMeta;

if ((Modes?.Length ?? 0) != 0 && Modes.Any(mode => mode != null))
meta.Modes = Modes;

if (Mountain != null)
meta.Mountain = Mountain;

if (CompleteScreen != null)
meta.CompleteScreen = CompleteScreen;

if (LoadingVignetteScreen != null)
meta.LoadingVignetteScreen = LoadingVignetteScreen;

if (LoadingVignetteText != null)
meta.LoadingVignetteText = LoadingVignetteText;

if (CassetteModifier != null)
meta.CassetteModifier = CassetteModifier;
}
}

public void ApplyToForOverride(AreaData area) {
Expand Down Expand Up @@ -405,41 +382,6 @@ public void ApplyTo(patch_AreaData area, AreaMode mode) {
}
area.Mode[(int) mode] = props;
}

public void AddTo(MapMetaModeProperties other) {
if (AudioState != null) {
if (other.AudioState == null) {
other.AudioState = AudioState;
} else {
AudioState.AddTo(other.AudioState);
}
}
if (Checkpoints != null) { other.Checkpoints = Checkpoints; }
if (IgnoreLevelAudioLayerData != null) { other.IgnoreLevelAudioLayerData = IgnoreLevelAudioLayerData; }
if (!string.IsNullOrEmpty(Inventory)) { other.Inventory = Inventory; }
if (!string.IsNullOrEmpty(Path)) { other.Path = Path; }
if (!string.IsNullOrEmpty(PoemID)) { other.PoemID = PoemID; }
if (!string.IsNullOrEmpty(StartLevel)) { other.StartLevel = StartLevel; }
if (HeartIsEnd != null) { other.HeartIsEnd = HeartIsEnd; }
if (SeekerSlowdown != null) { other.SeekerSlowdown = SeekerSlowdown; }
if (TheoInBubble != null) { other.TheoInBubble = TheoInBubble; }
}

public static MapMetaModeProperties Add(MapMetaModeProperties self, MapMetaModeProperties other) {
switch ((self, other)) {
case (null, null):
return new MapMetaModeProperties();
case (null, _):
return other;
case (_, null):
return self;
default:
MapMetaModeProperties result = new MapMetaModeProperties();
other.AddTo(result);
self.AddTo(result);
return result;
}
}
}
public class MapMetaAudioState {
public MapMetaAudioState() {
Expand All @@ -458,11 +400,6 @@ public void Parse(BinaryPacker.Element meta) {
meta.AttrIf("Music", v => Music = v);
meta.AttrIf("Ambience", v => Ambience = v);
}

public void AddTo(MapMetaAudioState other) {
if (!string.IsNullOrEmpty(Music)) { other.Music = Music; }
if (!string.IsNullOrEmpty(Ambience)) { other.Ambience = Ambience; }
}
}
public class MapMetaCheckpointData {
public MapMetaCheckpointData() {
Expand All @@ -474,14 +411,14 @@ public MapMetaCheckpointData(BinaryPacker.Element meta) {

public string Level { get; set; }
public string Name { get; set; }
public bool? Dreaming { get; set; }
public bool Dreaming { get; set; }
public string Inventory { get; set; }
public MapMetaAudioState AudioState { get; set; }
public string[] Flags { get; set; }
public Session.CoreModes? CoreMode { get; set; }
public CheckpointData Convert()
=> new CheckpointData(Level, Name, MapMeta.GetInventory(Inventory), Dreaming ?? false, AudioState?.Convert()) {
Flags = new HashSet<string>(Flags ?? Array.Empty<string>()),
=> new CheckpointData(Level, Name, MapMeta.GetInventory(Inventory), Dreaming, AudioState?.Convert()) {
Flags = new HashSet<string>(Flags ?? new string[0]),
CoreMode = CoreMode
};

Expand All @@ -506,16 +443,6 @@ public void Parse(BinaryPacker.Element meta) {
}
}
}

public void AddTo(MapMetaCheckpointData other) {
if (!string.IsNullOrEmpty(Level)) { other.Level = Level; }
if (!string.IsNullOrEmpty(Name)) { other.Name = Name; }
if (Dreaming != null) { other.Dreaming = Dreaming; }
if (!string.IsNullOrEmpty(Inventory)) { other.Inventory = Inventory; }
if (AudioState != null) { other.AudioState = AudioState; }
if (Flags != null) { other.Flags = Flags; }
if (CoreMode != null) { other.CoreMode = CoreMode; }
}
}
public class MapMetaMountain {
public string MountainModelDirectory { get; set; } = null;
Expand Down
18 changes: 18 additions & 0 deletions Celeste.Mod.mm/Patches/AreaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,28 @@ public static patch_AreaData Get(string sid) {
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.Meta = 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) {
patch_ModeProperties[] larger = new patch_ModeProperties[3];
for (int i = 0; i < area.Mode.Length; i++)
Expand All @@ -274,6 +291,7 @@ public static patch_AreaData Get(string sid) {

// Some special handling.
area.OnLevelBegin = (level) => {
MapMeta levelMeta = patch_AreaData.Get(level.Session).Meta;
MapMetaModeProperties levelMetaMode = ((patch_MapData) level.Session.MapData).Meta;
if (levelMetaMode?.SeekerSlowdown ?? false)
Expand Down
54 changes: 17 additions & 37 deletions Celeste.Mod.mm/Patches/MapData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,12 @@ private static BinaryPacker.Element _Process(BinaryPacker.Element root, MapData
}

private BinaryPacker.Element Process(BinaryPacker.Element root) {
if (root.Children == null) {
ProcessMeta(null);
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) {
if (root.Children.Find(element => element.Name == "meta") is BinaryPacker.Element meta)
ProcessMeta(meta);
} else {
ProcessMeta(null);
}

new MapDataFixup(this).Process(root);

Expand All @@ -191,33 +186,8 @@ private void ProcessMeta(BinaryPacker.Element meta) {
patch_AreaData area = patch_AreaData.Get(Area);
AreaMode mode = Area.Mode;

MapMeta metaParsedFromFile = null;
MapMeta metaParsed = null;

// load metadata from .meta.yaml file
string path = $"Maps/{area.Mode[(int)mode].Path}";
if (Everest.Content.TryGet(path, out ModAsset asset)) {
metaParsedFromFile = asset.GetMeta<MapMeta>();
if (metaParsedFromFile != null) {
metaParsedFromFile.Modes[(int)mode] = MapMetaModeProperties.Add(metaParsedFromFile.Mode, metaParsedFromFile.Modes[(int)mode]);
metaParsedFromFile.Mode = null;
}
}

// load metadata from .bin file
if (meta != null) {
metaParsed = new MapMeta(meta);
metaParsed.Modes[(int)mode] = MapMetaModeProperties.Add(metaParsed.Mode, metaParsed.Modes[(int)mode]);
metaParsed.Mode = null;
}

// merge metadata, with .meta.yaml taking priority
metaParsed = MapMeta.Add(metaParsedFromFile, metaParsed);

// apply metadata to AreaData
if (mode == AreaMode.Normal) {
metaParsed.ApplyTo(area);
metaParsed.Modes[(int)mode]?.ApplyTo(area, mode);
new MapMeta(meta).ApplyTo(area);
Area = area.ToKey();

// Backup A-Side's Metadata. Only back up useful data.
Expand All @@ -230,10 +200,20 @@ private void ProcessMeta(BinaryPacker.Element meta) {
CoreMode = area.CoreMode,
Dreaming = area.Dreaming
};
} else {
MapMeta combinedMeta = MapMeta.Add(metaParsed, area.Meta);
area.Mode[(int)mode].MapMeta = combinedMeta;
combinedMeta.Modes[(int)mode]?.ApplyTo(area, mode);
}

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.Meta.Modes
};
area.Mode[(int) mode].MapMeta = mapMeta;
}
}

Expand Down

0 comments on commit dc0d4cb

Please sign in to comment.