Skip to content

Commit

Permalink
Revert metadata loading change
Browse files Browse the repository at this point in the history
  • Loading branch information
maddie480 committed Nov 30, 2024
1 parent 47405a8 commit b5bab9d
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 209 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
72 changes: 39 additions & 33 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 All @@ -297,25 +315,30 @@ public static patch_AreaData Get(string sid) {
}
}

// 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++) {
// Check for .bins possibly belonging to A side .bins by their path and lack of existing modes.
patch_AreaData area = Areas[i];
string path = area.Mode[0].Path;
ParseName(path, out int? order, out AreaMode side, out string name);
if (side == AreaMode.Normal) continue;
int otherIndex = Areas.FindIndex(other => other.Mode.Any(otherMode => otherMode?.Path == path));
if (otherIndex != -1 && otherIndex != i) {
Areas.RemoveAt(i);
i--;
continue;
}

Logger.Verbose("AreaData", $"Checking for area to attach {side} {i} ({area.Mode[0].Path}) to...");
ParseName(path, out int? order, out AreaMode side, out string 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++) {
patch_AreaData other = Areas[ii];
ParseName(other.Mode[0].Path, out int? otherOrder, out AreaMode otherSide, out string otherName);
if (otherSide != AreaMode.Normal) continue;

if (area.LevelSet == other.LevelSet && order == otherOrder && name == otherName && side != otherSide &&
!other.HasMode(side)) {

Logger.Verbose("AreaData", $"Found: {ii} ({other.Mode[0].Path})");

if (other.Mode[(int) side] == null)
other.Mode[(int) side] = new patch_ModeProperties {
Inventory = PlayerInventory.Default,
Expand All @@ -333,12 +356,6 @@ public static patch_AreaData Get(string sid) {
patch_AreaData area = Areas[i];
area.ID = i;

// 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 patch_MapData(area.ToKey());

// Clean up non-existing modes.
int modei = 0;
for (; modei < area.Mode.Length; modei++) {
Expand All @@ -350,6 +367,14 @@ public static patch_AreaData Get(string sid) {

Logger.Verbose("AreaData", string.Format("{0}: {1} - {2} sides", i, area.SID, area.Mode.Length));

// 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 patch_MapData(area.ToKey());

if (area.IsInterludeUnsafe())
continue;

Expand All @@ -372,25 +397,6 @@ public static patch_AreaData Get(string sid) {
area.Mode[mode].MapData = new patch_MapData(area.ToKey((AreaMode) mode));
}
}

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

for (int i = 0; i < Areas.Count; i++) {
// Remove AreaDatas which are now a mode of another AreaData.
// This can happen late as the map data (.bin) can contain additional metadata.
patch_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) {
Logger.Verbose("AreaData", $"Removing area {i} since it has the same path {path} as one of area {otherIndex}'s modes");
Areas.RemoveAt(i);
i--;
}
}
for (int i = 0; i < Areas.Count; i++) {
Areas[i].ID = i;
}

// Load custom mountains
// This needs to be done after areas are loaded because it depends on the MapMeta
Expand Down
Loading

0 comments on commit b5bab9d

Please sign in to comment.